From f2c64456818dfd502678df933c2c3bdcb338bab1 Mon Sep 17 00:00:00 2001 From: Suraj Yadav Date: Mon, 27 Apr 2026 21:55:16 +0530 Subject: [PATCH] docs(forms): add NG01902 error reference and link to docs Add the NG01902 (Orphan field in signal forms) documentation page to the Error Encyclopedia and change the ORPHAN_FIELD_PROPERTY error code to -1902 so Angular's RuntimeError automatically appends a link to angular.dev/errors/NG01902 in the thrown error message. --- adev/src/content/reference/errors/NG01902.md | 26 +++++++++++++++++++ adev/src/content/reference/errors/overview.md | 1 + packages/forms/signals/src/errors.ts | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 adev/src/content/reference/errors/NG01902.md diff --git a/adev/src/content/reference/errors/NG01902.md b/adev/src/content/reference/errors/NG01902.md new file mode 100644 index 00000000000..875e433e5b3 --- /dev/null +++ b/adev/src/content/reference/errors/NG01902.md @@ -0,0 +1,26 @@ +# Orphan field in signal forms + +This error indicates that a `Field` instance is no longer connected to the current model structure. +Angular signal forms throw `NG01902` when a field path that previously existed can no longer be resolved as the same property in the parent object. + +A common trigger is unintentionally setting a field's value to `undefined`. +In signal forms, `undefined` means "field does not exist", so an existing field can become orphaned. + +## Why this happens + +Signal forms keep field instances in sync with your model shape. +If code still references an older field instance after the model shape changed, Angular detects the mismatch and throws this error. + +This can happen when: + +- a property is removed from the model object +- a property becomes `undefined` instead of remaining present +- code holds a stale field reference across structural updates + +## How to fix it + +- Avoid writing `undefined` to model fields. Use `null` or another explicit value when the field should still exist. +- Keep the model shape stable while a field is in use. +- Re-read fields from the current form tree after structural updates instead of reusing stale references. + +For model design guidance, see [Avoid `undefined`](/guide/forms/signals/model-design#avoid-undefined). diff --git a/adev/src/content/reference/errors/overview.md b/adev/src/content/reference/errors/overview.md index 2f036e99b2f..b7cdd5d6b64 100644 --- a/adev/src/content/reference/errors/overview.md +++ b/adev/src/content/reference/errors/overview.md @@ -39,6 +39,7 @@ | `NG01002` | [Missing Control Value](errors/NG01002) | | `NG01101` | [Wrong Async Validator Return Type](errors/NG01101) | | `NG01203` | [Missing value accessor](errors/NG01203) | +| `NG01902` | [Orphan field in signal forms](errors/NG01902) | | `NG02200` | [Missing Iterable Differ](errors/NG02200) | | `NG02800` | [JSONP support in HttpClient configuration](errors/NG02800) | | `NG02802` | [Headers not transferred by HttpTransferCache](errors/NG02802) | diff --git a/packages/forms/signals/src/errors.ts b/packages/forms/signals/src/errors.ts index c324bc4c51f..35a8467fedf 100644 --- a/packages/forms/signals/src/errors.ts +++ b/packages/forms/signals/src/errors.ts @@ -14,7 +14,7 @@ export const enum RuntimeErrorCode { // Signal Forms errors (1900-1999) PATH_NOT_IN_FIELD_TREE = 1900, PATH_RESOLUTION_FAILED = 1901, - ORPHAN_FIELD_PROPERTY = 1902, + ORPHAN_FIELD_PROPERTY = -1902, ORPHAN_FIELD_ARRAY = 1903, ORPHAN_FIELD_NOT_FOUND = 1904, ROOT_FIELD_NO_PARENT = 1905,