Skip to content

Both designer field shapes spell the spec's system flag as isSystem — so system-field detection reads a key the server never sends, and the key round-trips back out as a 422 #6044

Description

@yinlianghui-tw

Surfaced by the key-level parity gate built for #5761 (scripts/check-designer-field-key-parity.mjs). Filed, not fixed, per #5761's ruling.

The key

isSystem is not in FieldSchema's accept set; the spec spells it system:

system — Auto-injected system/audit field (e.g. created_at, updated_by, organization_id). Tools that surface system fields separately from author-declared business fields should branch on this flag.

FieldSchema.safeParse({ type:'text', label:'L', isSystem: true })
=> success = false
=> [{ code: 'unrecognized_keys', keys: ['isSystem'] }]

Two distinct defects, one misspelling

1. The READ is dead (the quieter, probably worse half).

packages/plugin-designer/src/MetadataFieldsPage.tsx:95toDesignerField does isSystem: raw.isSystem. raw is what the server sent, and a spec-parsed server sends system. So raw.isSystem is always undefined and every field loads as non-system.

That flag is load-bearing in the UI. FieldDesigner.tsx:188 refuses to delete a system field (if (!field || field.isSystem) return;) and :299,301 disable the name and type inputs for one. With the read dead, organization_id, created_at and friends present as ordinary editable, deletable business fields in the field designer. Nothing goes red — the flag is optional, so undefined is a valid "not a system field".

2. The WRITE can round-trip out as a 422.

ServerFieldSchema declares [key: string]: unknown and fromDesignerField spreads carryOver(prev) verbatim to preserve unknown keys. carryOver strips only RETIRED_FIELD_KEYS = ['indexed']. So any isSystem present on the previous server payload is carried straight back out to PUT /api/v1/meta/object/:name, where it is a hard 422 INVALID_METADATA blocking every later save. FieldDesigner.tsx:244 also seeds isSystem: false on newly created fields.

Whether a live 422 exists today depends on whether anything upstream ever emits isSystem — that is worth measuring rather than assuming, and it is why this card is filed separately from the two live-control instances (#6041referenceTo, #6043formula) rather than folded in with them.

Scope note for whoever takes it

Do not resolve it by adding isSystem to RETIRED_FIELD_KEYS. That would strip the key while leaving the read still broken, i.e. close the 422 and fossilize the dead system-field detection. Both directions belong to this card. MetadataObjectsPage.tsx / ObjectManager.tsx also carry an isSystem on the object shape — a separate schema, check it separately rather than assuming it is the same defect.

Verification

pnpm check:designer-field-key-parity reports it on both ServerFieldSchema and DesignerFieldDefinition; recorded in that gate's KNOWN_UNPARSEABLE_KEYS ledger pointing here.

Refs: #5761 (the gate) · #6041 · #6043 · #4644

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions