docs(data-modeling): stop crediting field format with validation - #19847
Merged
objectstack-fleet[bot] merged 1 commit intoSep 24, 2026
Merged
Conversation
The write-time record validator keys its email/url/phone shape checks on the field `type` and never reads a field's `format`. Six hand-written rows (plus the quick-summary `text` row) said otherwise, and three declared a `format` default that does not exist. - `text` rows now say what the key is: a display hint read by the UI's cell-renderer resolver for a small word set, with no server-side check. - The `phone` gallery row promised a pattern nothing implements; removed. - `email` / `url` / `phone` validation tables list the bounds the validator does enforce and say the shape check keys on `type`. Claude-Session: https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Sep 23, 2026
Contributor
Author
Contract reviewServed-tier: ① Derived judgments
② Semver levelDocs-only ③ Boundary flags
Implemented-by: VERDICT: PASS Isolated at-tier reviewer, adopted by the Generated by Claude Code |
objectstack-fleet
Bot
deleted the
claude/issue-19764-field-format-doc-rows
branch
September 24, 2026 16:02
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Sep 28, 2026
…(field type or a format rule) (objectstack-ai#19878) Fixes objectstack-ai#19848 Clause-②: no ## What changed `content/docs/api/error-catalog.mdx` only. 1. **The `INVALID_FORMAT` entry.** Its **Fix** line told authors to match "the field's `format` constraint". No write-time check reads a field-level `format` key, so following that advice changes nothing. The entry now says what actually decides: - **No route emits the top-level `INVALID_FORMAT` today.** The entry now says so and tells clients to branch on `VALIDATION_FAILED` + `fields[].code`. That is the same shape the page's `INVALID_REFERENCE` entry already uses. - **The field `type`.** The built-in email / url / phone checks key on `type` and answer `invalid_email` / `invalid_url` / `invalid_phone`. Date and time parse failures answer `invalid_date` / `invalid_time`. - **A `format` validation rule** (a different key: its `regex` or its named `format` `email` | `url` | `phone` | `json`) answers field-level `invalid_format`. The link goes to `/docs/data-modeling/validation#format-validation`, the anchor PR objectstack-ai#19847 uses. - Field-level `invalid_format` is also emitted for a missed declared `pattern` outside record metadata: a settings value, or a request body a route parses with Zod. - The Fix line now names the field `type` or the `format` validation rule as the things to change, and says a field-level `format` key runs no write-time check on any field type. 2. **A bounded in-place fix in the same file (declared here).** The `VALIDATION_ERROR` JSON example showed an email miss as `"code": "invalid_format"`. The Zod mapper answers `invalid_email` for that miss. See the Acceptance notes. The wording follows PR objectstack-ai#19847 (still open at the time of writing; this PR depends on none of its files) and the spec's `format` describe: "keyed on `type`", "a field-level `format` key is not read", "a `format` validation rule". ## Evidence (all at base `2bbb4623`) | Claim | Where | |:---|:---| | Record validator never reads field `format`: `def.format` 0 hits, same-file control `def.type` 7 | `packages/objectql/src/validation/record-validator.ts` | | email / url / phone checks key on `type`, emit `invalid_email` / `invalid_url` / `invalid_phone` | `record-validator.ts:746-754` | | date / time parse failures emit `invalid_date` / `invalid_time` | `record-validator.ts:839`, `:858` | | A `format` validation rule (regex or named format) emits field-level `invalid_format` | `packages/objectql/src/validation/rule-validator.ts:2776-2790` (check), `:2822` (`formatViolation`) | | Settings `pattern` miss emits field-level `invalid_format` | `packages/services/service-settings/src/settings-service.ts:2042` | | Zod-parsed routes: email to `invalid_email`, url to `invalid_url`, other format/regex to `invalid_format` | `packages/spec/src/api/zod-issues-to-fields.ts:82-85` | | Top-level `INVALID_FORMAT` has no producer: `git grep INVALID_FORMAT` outside tests and `dist` hits only the enum member `packages/spec/src/api/errors.zod.ts:57`, the ADR note and the unpinned baseline | `scripts/error-status-unpinned-baseline.json:15` ("documented with an HTTP status that NO producer ... declares"); ADR-0114 line 37 records the six field-shaped top-level members as a known wart | | Spec contract on the field key | `packages/spec/src/data/field.zod.ts:1090-1094` (the `format` describe: "the write-time record validator's built-in email, url and phone checks key on `type`, never on this key") | ## Verification (final head `40758ef8`) - `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` derived **41** commands. I ran all 41 on `40758ef8`: 41 exited 0. - Reconciliation: `--ran` printed `41 derived famil(ies) accounted for — 41 run, 0 NOT-MEASURED (a DERIVED zero — all 41 recorded an exit code and none of them is 3)`. - On the first pass (`d56a2a7f`), four gates exited **3 (PREREQUISITE NOT MET)**: `check:doc-formula-expressions`, `check:doc-security-posture`, `check:skill-examples` and `check:docs-transcript-drift`. The lint, formula and client packages had not been built yet. After those builds all four re-ran with exit 0. - `pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/api/error-catalog-docs.test.ts` (the test that reads this page against the wire face): `Test Files 1 passed (1) · Tests 5 passed (5)` on `40758ef8`. - Not measured, and owned by CI: the families `dispatch-gates` lists outside its derived total, and the path-scheduled `Build Docs` / `Test Core` jobs. ## Changeset Docs-only. `content/docs/**` is not in any package's `files[]`, so this PR publishes nothing and falls under `skip-changeset`. Per the dispatch, this seat writes no labels. ## Acceptance notes - **Bounded in-place fix (the `VALIDATION_ERROR` example `invalid_format` → `invalid_email`).** All four exemption conditions hold: - same defect class (a docs line that says `format` where the real check keys on the email type); - a mechanical, pinned form (`zod-issues-to-fields.ts:83`); - the file is this card's claimed file; - the same gate family. It lies outside the claim's declared "(the `INVALID_FORMAT` entry)" sub-surface. The claim's file surface needs this entry added. - **`content/docs/ui/forms.mdx:229`** (`400 VALIDATION_FAILED` · "object schema validators fail (`required`, `format`, `length`, …)"): read, not edited. It lists kinds of constraint in the `When` column and gives no fix, so it does not tell anyone to edit a field `format` key. It does not carry the same false meaning. Not listed as a defect. - **Sibling entries on the same page (a finding, not fixed here):** `VALUE_TOO_LONG` and `VALUE_TOO_SHORT` also have no producer (`git grep` outside tests/`dist`: 0 hits each; control `'VALIDATION_FAILED'`: 70). Both appear in `scripts/error-status-unpinned-baseline.json`. The page still documents them as live causes. The record validator answers field-level `max_length` / `min_length` under `VALIDATION_FAILED` instead. This is reported to the seat for filing and is out of scope for this card. --- _Generated by [Claude Code](https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #19764
Clause-②: no
Two hand-written data-modeling pages credited a field's
formatkey with validation. The write-time record validator keys its email / url / phone shape checks on the fieldtypeand reads a field'sformatzero times; three rows also declared aformatdefault that does not exist. Every rewritten row now names only behaviour a reader delivers.Refs read: objectstack
245e161a(base71ef2219), objectui pin87af769e9a3e(the.objectui-shaonmainwhen this was worked).Rows: old text, new text, the reader that makes the new text true
field-types.mdx### text,formatphone/tel/telephone,email,url/uri/link,currency/money,percent/percentage); any other word renders as plain text; to reject malformed values use the fieldtypeor aformatvalidation rulepackages/fields/src/index.tsx:2915FORMAT_TO_RENDERER,:2929TEXTUAL_BASE_TYPES,:2943-2944promotion; pinned bypackages/plugin-grid/src/__tests__/formatHintedColumnRenderer-8920.test.tsx:135. No-server-check:packages/objectql/src/validation/record-validator.tsreadsdef.format0 times. Spec agreement:packages/spec/src/data/field.zod.ts:1090describefield-types.mdx### phone,format:2943), and objectuipackages/fields/src/widgets/PhoneField.tsxmentionsformat0 times; record-validator:752checkst === 'phone'with a fixedPHONE_RE(:108)validation-rules.mdx### text,formattextit is a display hint (links to the gallery); to constrain shape use theemail/url/phonetype or aformatvalidation ruleformatvalidation rule,packages/objectql/src/validation/rule-validator.ts:2765checkFormat, documented atcontent/docs/data-modeling/validation.mdx:146validation-rules.mdx### email,formatdefaultemaillocal@domainshape"maxLength/minLength; the Default constraints line adds that the check keys ontype: 'email'and a field-levelformatis not read:746(t === 'email'),:91EMAIL_RE; bounds:693BOUNDED_STRING_FIELD_TYPESbranch,:696/:699;emailis in that set (field.zod.ts:136)validation-rules.mdx### url,formatdefaulturltype: 'url':749,:107URL_RE; bounds as row 4validation-rules.mdx### phone,formatdefaultphonetype: 'phone', plus a pointer to aformatvalidation rule with aregexfor a stricter shape:752,:108PHONE_RE; bounds as row 4;checkFormatas row 3validation-rules.mdxQuick Validation Summary,textKey ConstraintsmaxLength,minLength,format,valueDomain"maxLength,minLength,valueDomain(formatis a display hint, not a constraint)"Six was a floor. Instrument for the census:
git grep -nEfor a backtickedformat, forformat: 'email|url|phone|tel', and forField.text({ ... formatovercontent/docs/**minusreferences/andreleases/(14 files hit). Control: backtickedmaxLengthhits 14 times invalidation-rules.mdx. Rows in the two pages: the six plus row 7 above. Autonumber: neither page documents theformatreading onautonumber(both documentautonumberFormat), so that meaning is untouched and nothing here contradictsfield.zod.ts:1091.The spec wins where they meet. These rows now agree with the landed
formatdescribe (field.zod.ts:1090-1094): no vocabulary, no server check offautonumber, a display hint the UI owns, and constrain values throughtypeor aformatvalidation rule.Changeset
Docs-only.
content/docs/**ships in no package'sfiles[], so this isskip-changesetterritory. Per the dispatch, no label write from this seat.Verification (at
245e161a)node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commandsderived 40 commands for this diff. All 40 exit 0. Four first exited 3 with PREREQUISITE NOT MET, which is not a measurement:check:doc-formula-expressions,check:doc-security-posture,check:skill-examplesandcheck:docs-transcript-drift. After building@objectstack/spec, the@objectstack/lintclosure,@objectstack/formulaand@objectstack/client-react, they exited 0 when re-run.--ranreconciliation: "40 derived famil(ies) accounted for — 40 run, 0 NOT-MEASURED (a DERIVED zero — all 40 recorded an exit code and none of them is 3)". It includescheck:doc-anchors(0) andcheck:nul-bytes(0). NOT MEASURED locally: the CI-only lanes the tool lists outside the 40, including Build Docs and the type-check lanes.Acceptance notes
content/docs/api/error-catalog.mdx:201(INVALID_FORMATFix line) says to match "the field'sformatconstraint". That is the same false claim on another page. Out of this card's file surface, so it is not edited here. Class (b); dedupe words:INVALID_FORMAT,error-catalog,field format constraint.content/docs/ui/forms.mdx:229listsformatamong "object schema validators". It is ambiguous: it may name theformatvalidation rule, which is real. Noted only.textareais in the resolver'sTEXTUAL_BASE_TYPES, but its tables list noformatrow. No false claim, so nothing was added.Generated by Claude Code