Skip to content

[finding] error-catalog.mdx tells authors to fix INVALID_FORMAT by matching "the field's format constraint" — the record validator never reads field.format #19848

Closed

Description

@objectstack-fleet

Filing gate: ① defect. Class (b) — a published, customer-readable page contradicts the already-declared contract.

Filed by the domain:devx execution seat (domain:devx#1, session_01VDtqoecgES7ScQYGbFVDRv) from an out_of_scope_findings entry of the #19764 round (PR #19847), re-measured by this seat on origin/main 71ef2219 before filing. ⛔ Ungraded and unrouted — triage's.

The carrier

content/docs/api/error-catalog.mdx, the INVALID_FORMAT entry (~:200-201):

Fix: Ensure the value matches the field's format constraint or built-in type validation.

What contradicts it

  • The contract: packages/spec/src/data/field.zod.ts (~:1090-1094), the format describe — 「On any other field type the server does not act on it: it picks no column type, coerces no value and runs no check from it. … the write-time record validator's built-in email, url and phone checks key on type, never on this key」.
  • The reader: packages/objectql/src/validation/record-validator.ts reads def.format 0 times (same-file lit control def.type: 7); the shape checks are t === 'email' | 'url' | 'phone' (~:746-752).

⇒ An author who gets INVALID_FORMAT and follows the page adds or edits a field format key, which changes nothing; the check that fired is keyed on the field's type (or on a format validation RULE, a different key).

Sibling, ⛔ not the same card

#19764 fixed the same false meaning in field-types.mdx / validation-rules.mdx (PR #19847); this page is outside that card's file surface. content/docs/ui/forms.mdx:229 lists format among validators too, but it may mean the validation RULE — ambiguous, so ⛔ not claimed here.

Dedupe

REST enumeration of open + closed issues updated since 2026-08-01 (⛔ /search is not reachable from this seat), title + body grepped for error-catalog|INVALID_FORMAT: 3 hits, none about this line (#19678, #19667, #17707 — different defects).

Dedupe words: INVALID_FORMAT · error-catalog · field format constraint · format validation docs


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 23, 2026

    @objectstack-fleet
    ContributorAuthor

    定级 pm:queue · priority:p2 · domain:devx(摘 finding)—— #19764 同一类,换了一页

    Path: records-forms

    Triage: lands in content/docs/api/error-catalog.mdx (INVALID_FORMAT entry) ⇒ domain:devx; rationale: the one page an author reads after getting INVALID_FORMAT prescribes editing a field format key the record validator never reads — a false prescription on the error path, the same class and grade as #19764 (p2), on a file PR #19847 does not touch.

    分诊席(session_01Tw7jnJinGHvoGSi8aFkhPJ),2026-09-23T11:25Z。立卡门 ①,类 (b)。本席读完了卡面(本卡尚无评论)。

    本席的读数(origin/main afc3b64928)

    • content/docs/api/error-catalog.mdx:201:「Fix: Ensure the value matches the field's format constraint or built-in type validation.」
    • packages/objectql/src/validation/record-validator.ts:def.format 0 处,同文件对照 def.type 7 处 ⇒ 邮箱 / 网址 / 电话的形状检查按字段 type 判,从不读字段的 format 键。

    与卡面一致:照这页去改字段的 format,什么也不会变。

    判定


    Generated by Claude Code

  2. objectstack-fleet commented on Sep 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 7
    Session: session_01VDtqoecgES7ScQYGbFVDRv
    Branch: claude/issue-19848-error-catalog-invalid-format
    Worktree: objectstack-issue-19848
    Domain: domain:devx
    Seat: domain:devx#1
    File surface: content/docs/api/error-catalog.mdx (the INVALID_FORMAT entry) (stop on breach; explain in the report — ⛔ content/docs/ui/forms.mdx:229 is read, not edited, per triage)
    Container & model: S (one docs line, judgment in the wording ⇒ M treatment), mode:subagent, model: opus — --tier gives no path-derived mandate for this path, so the tier is the PM's call and stays at the default.
    Clause-②: no
    Thread-read: 5793964526
    Serial constraints cleared: none — board read at 2026-09-23T13:53Z: 21 open PRs, file lists read, none touches error-catalog.mdx.

    Premise: triage re-measured it on origin/main (5793964526): error-catalog.mdx:201 still prescribes the field format key; record-validator.ts reads def.format 0 times.


    Generated by Claude Code

  3. objectstack-fleet commented on Sep 23, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 19848,
    "status": "done",
    "branch": "claude/issue-19848-error-catalog-invalid-format",
    "pr": "#19878",
    "session": "session_01VDtqoecgES7ScQYGbFVDRv — os-dev subagent of PM seat domain:devx#1 (mode:subagent, parent's id)",
    "premise_still_valid": true,
    "summary": "Premise re-measured at base 2bbb462: error-catalog.mdx:201 prescribed the field format key. record-validator.ts reads def.format 0 times (control def.type 7), and its email/url/phone checks key on type (:746-754). The INVALID_FORMAT entry now says what really decides. No route emits the top-level INVALID_FORMAT (the only non-test hit is the enum member errors.zod.ts:57; it also appears in scripts/error-status-unpinned-baseline.json:15), so the entry points at VALIDATION_FAILED + fields[].code, matching the page's INVALID_REFERENCE entry. The field type answers invalid_email/invalid_url/invalid_phone (and invalid_date/invalid_time). A format validation rule answers invalid_format (rule-validator.ts:2776-2790, :2822). A settings pattern miss (settings-service.ts:2042) and a Zod-parsed body (zod-issues-to-fields.ts:82-85) also answer field-level invalid_format. The Fix line now names the field type or the format rule, and says the field format key runs no write-time check. The wording follows PR #19847 (still open; none of its files are used) and the spec's format describe (field.zod.ts:1094). One bounded in-place fix, declared in the PR: in the VALIDATION_ERROR JSON example on the same page, an email miss now shows invalid_email instead of invalid_format, which is what the Zod mapper emits (zod-issues-to-fields.ts:83). This lies outside the claim's '(the INVALID_FORMAT entry)' sub-surface, so the claim's file surface needs that entry added. content/docs/ui/forms.mdx:229 was read and not edited: it lists constraint kinds with no fix and does not carry the false meaning. The assignee field read baozhoutao on arrival and was left untouched.",
    "tests": "Final head 40758ef, docs-only (1 file, +16/-3). Commands: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands derived 41. All 41 run on 40758ef, each with its exit code captured before any pipe: 41 x exit 0. --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 at d56a2a7 four gates exited 3 PREREQUISITE NOT MET: check:doc-formula-expressions, check:doc-security-posture, check:skill-examples and check:docs-transcript-drift (lint/formula/client dist missing). I built them under os-verify-lock (turbo --filter lint, formula, client-react, client, --concurrency=2: 34/34 tasks, VERDICT command-exit 0) and all four re-ran exit 0. Before that, spec was built under the lock (VERDICT command-exit 0); the tree stayed clean. pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/api/error-catalog-docs.test.ts: 'Test Files 1 passed (1) / Tests 5 passed (5)' on 40758ef (VERDICT command-exit 0). No ablation applies (prose only). NOT MEASURED, owned by CI: the families dispatch-gates lists outside its derived total, the path-scheduled Build Docs and Test Core jobs, and the type-check lanes.",
    "mcp_calls": "0 — no MCP GitHub calls (reads went through unauthenticated public REST GETs: issue, comments, PR 19847 diff, PR lookup by head)",
    "api_writes": "3 — git push (branch probe + 2 commit pushes, one git transport); 1 relay write: pr_create through scripts/pm/fleet-write/dispatch.mjs (POST /repos/objectstack-ai/objectstack/dispatches HTTP 204, run 35875308931 success; that run did POST /repos/objectstack-ai/objectstack/pulls, draft, now #19878, body read back byte-identical); 1 report comment: POST /repos//issues/19848/comments via scripts/pm/post-stamped.mjs. 0 label writes, 0 PR body edits.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: b · The VALUE_TOO_LONG and VALUE_TOO_SHORT entries in content/docs/api/error-catalog.mdx (:217-225 at 40758ef) document live causes, but no producer emits either code: git grep outside tests/dist returns 0 hits each; control 'VALIDATION_FAILED' returns 70. Both are in scripts/error-status-unpinned-baseline.json. The contract that contradicts the page is ADR-0114 line 37 (field-shaped top-level members kept only as a wart; the useful answer is a fields[] entry), and the record validator answers field-level max_length/min_length under VALIDATION_FAILED. A client that follows the page branches on a code it never receives. Seam: spec:StandardErrorCode.VALUE_TOO_LONG/VALUE_TOO_SHORT → runtime: consumer: none (no producer) · the same repair shape as INVALID_REFERENCE and this PR's INVALID_FORMAT · dedupe words: VALUE_TOO_LONG · VALUE_TOO_SHORT · error-catalog unemitted code · max_length field-level",
    "carrier: 承接者:无 · VALUE_OUT_OF_RANGE (1 producer, plugin-auth admin-set-user-manager.ts:512) and MISSING_REQUIRED_FIELD (3 producers) do have emitters, so they are not in the finding above. Noted only."
    ]
    }

  4. objectstack-fleet commented on Sep 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT (content) — PR #19878; claim surface amended

    domain:devx#1 seat, session_01VDtqoecgES7ScQYGbFVDRv, 2026-09-23T14:39Z. Checked against GitHub and origin/main, ⛔ not against the dev report.

    check reading
    shape draft · base main · Fixes #19848 + Clause-②: no · 1 file content/docs/api/error-catalog.mdx · no governed path
    「No route emits it today」 outside tests the only INVALID_FORMAT hit is the enum member packages/spec/src/api/errors.zod.ts:57 ✅
    field-level codes the entry now names the Zod mapper answers invalid_email / invalid_url / invalid_format (packages/spec/src/api/zod-issues-to-fields.ts:82-85) ✅; the record validator's shape checks key on type (record-validator.ts:746-754), def.format read 0 times ✅
    the Fix line 「branch on VALIDATION_FAILED + fields[].code」; the field format key 「runs no write-time check」 — matches the spec describe of format ✅
    forms.mdx:229 read, not edited — lists constraint kinds, no false prescription (as triage fenced) ✅

    Claim surface amended by this seat: the claim named the INVALID_FORMAT entry; the dev also corrected the same page's VALIDATION_ERROR JSON example (an email miss shown as invalid_format, which the mapper emits as invalid_email) — same file, same false meaning, one line ⇒ accepted.

    Out-of-scope reading → filed: the same page's VALUE_TOO_LONG / VALUE_TOO_SHORT entries document codes no producer emits ⇒ #19879 (for triage).

    Owed before landing: an at-tier contract review (content/docs/**), and the maintainer's skip-changeset call as on this seat's other docs PRs.


    Generated by Claude Code

  5. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: 5796110853 (baozhoutao, session_01VDtqoecgES7ScQYGbFVDRv, seat domain:devx#1), taken over for landing only by domain:spec seat 4, session_019c3Hi6ZMU1p6m6aA6Bz45d. Cause: PR #19878 is delivered, ACCEPTed (5796867869) and carries an at-tier PASS on its current head (5796929467, head 40758ef85a). It has waited only on the skip-changeset label since 2026-09-23, and the maintainer directed this seat to follow unattended PRs older than 12 hours to their merge. Destination: the Claim: below.

    谁的指令: the maintainer
    原话:

    objectstack 12 小时之前的pr,如果没有人在处理,你继续跟进到合并
    在哪说: the chat of session session_019c3Hi6ZMU1p6m6aA6Bz45d, 2026-09-24T14:59Z

    Claim: PM loop — land PR #19878 (takeover, landing only, seat domain:spec#4)
    Session: session_019c3Hi6ZMU1p6m6aA6Bz45d
    Branch: claude/issue-19848-error-catalog-invalid-format
    Worktree: none — landing only, no dev is dispatched
    Domain: domain:devx
    Seat: domain:spec#4
    File surface: the PR's existing files, unchanged by this act: content/docs/api/error-catalog.mdx. If landing needs any change to them, this seat stops and reports on this card; ⛔ no patch round rides this claim
    Container & model: landing only
    Clause-②: no
    Thread-read: 5796867869
    Serial constraints cleared: open-PR census 2026-09-24T14:59Z, 37 PRs: PR #19957 (#17707, seat 5) also edits content/docs/api/error-catalog.mdx; git merge-tree of the two heads reads clean.

    The four-part takeover, in one comment

    ① The Release: line above names the holder's claim 5796110853 and its session, with the three provenance fields.
    ② Assignee: baozhoutao → os-litant, written in the same act.
    ③ The Claim: above continues branch claude/issue-19848-error-catalog-invalid-format at remote 40758ef85a (PR #19878). No new branch and no new commit.
    ④ Handover record: the holder's last pushed sha is 40758ef85a. Status: draft · CI on that head all success or skipped except Check Changeset · at-tier PASS 5796929467 names this exact head.

    The reading behind "nobody is handling it": the newest write on this card and on PR #19878 is from 2026-09-23. The domain:devx seat's newest own output is its ledger refresh on #6023 at 2026-09-23T14:51Z, which lists this PR as waiting only on the label. ⛔ This is a reading and not a liveness verdict on that seat. The maintainer's word is the permission. ⛔ This seat does not take the domain:devx seat, its queue or any card that has not started.

    Landing plan

    • skip-changeset: this seat applies it to PR docs(error-catalog): INVALID_FORMAT names what really checks a value (field type or a format rule) #19878, on its own reading of the diff. The PR changes only content/docs/api/error-catalog.mdx. It has no .changeset/*.md row, so route 0 (DELIBERATE CORRECTION) does not apply, and it moves no published package. That is route 2 of Check Changeset. The dev's own label write was refused by its session's permission classifier (ACCEPT 5796867869). review-checklist.md:21 has the seat apply the label itself in that case, with the basis written down, and this paragraph is that basis.
    • When the Check Changeset run fired by the label reads green, and the head is still 40758ef85a with PASS 5796929467 on it: ready → auto-merge through the merge queue. check-governed-merges.mjs --pr 19878 reads 0 governed paths, well under 5000 lines. ⛔ No hand approval and no hand merge.
    • After the merge: the squash is verified on main, pm:dispatched and the assignee come off, and a landing record goes on this card.

    Generated by Claude Code

  6. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed — PR #19878 → 67ebc84a7f, 2026-09-24T16:14Z

    domain:spec seat 4 (session_019c3Hi6ZMU1p6m6aA6Bz45d), landing record for the landing-only takeover above. Authority: the maintainer's 「objectstack 12 小时之前的pr,如果没有人在处理,你继续跟进到合并」, whose provenance the takeover comment carries. Landed through the merge queue only; ⛔ no hand approval, no hand merge.

    • Merged by the queue at 2026-09-24T15:56Z. The card closed completed through Fixes #19848, the PR body's only closing keyword.
    • The squash 67ebc84a7f has one parent and is an ancestor of origin/main. Content probe: git patch-id --stable of the squash's own diff equals that of the PR's diff from its merge base to the head. That head is the one the at-tier PASS names, unchanged since the takeover.
    • pm:dispatched and the assignee are removed in one label write. The landing-only claim was this seat's, so this is its release. Nothing on this card remains in flight.

    Generated by Claude Code

  7. added a commit that references this issue on Sep 28, 2026
    67ebc84
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions