Skip to content

docs(api): INVALID_FIELD's searchFields clause covers the two value-shape refusals (#15882) - #16269

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-15882-error-catalog-searchfields-shape
Sep 6, 2026
Merged

docs(api): INVALID_FIELD's searchFields clause covers the two value-shape refusals (#15882)#16269
baozhoutao merged 1 commit into
mainfrom
claude/issue-15882-error-catalog-searchfields-shape

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Fixes #15882

What changed

Extended the searchFields parenthetical inside the ### INVALID_FIELD entry of content/docs/api/error-catalog.mdx (lines 71-80 on origin/main) so it also names the two value-shape refusals on that axis, alongside the existing "real field outside the searchable set" clause. No other entry in the file was touched.

Producer sites (verified on origin/main at dispatch tip 0e16fc454, re-read on the branch base 77781151d)

Both live in packages/metadata-protocol/src/protocol.ts, inside assertSearchFieldsAreSearchable (function starts :9788):

  • :9800-9807 — array-entry-not-a-string: '${param}' entry #${badShape + 1} on object '${object}' is not a field name. '${param}' narrows which columns 'search' scans, as a comma-separated string or an array of field names. Sets err.code = 'INVALID_FIELD' (line 9804), err.status = 400 (9805), err.param = param (9807).
  • :9813-9821 — value neither string nor array: '${param}' on object '${object}' must be a comma-separated string or an array of field names, received ${...}. Sets err.code = 'INVALID_FIELD' (9818), err.status = 400 (9819), err.param = param (9821).

Both confirmed: code = 'INVALID_FIELD', status = 400, and the offending name lands in param (not field) — matching the catalog's existing framing for this axis.

:9556 classification: that line ('${param}' entry #${badShape + 1} on object '${object}' is not a field name.) lives in assertProjectionFieldsExist, not assertSearchFieldsAreSearchable — it is the fields/projection axis's own array-shape refusal (the retired nested-select object form, { field, fields, alias }), a structurally identical message reused on a different parameter. It is not a third searchFields site. The card's "two" producer sites for searchFields stands; the fix covers exactly those two.

Denominator re-run

$ git grep -nE "code(: | = )'INVALID_FIELD'" -- 'packages/**/*.ts' | grep -v '\.test\.ts' | wc -l
22

Unchanged from triage's reading — 22 INVALID_FIELD assignment sites, of which the two above are the searchFields-axis shape refusals this PR's clause now names.

Framing

Per triage (endorsed and carried into this PR): the shape refusal is still field-name-flavoured — the value being refused is a list of field names. This is a coverage gap in one clause of the Cause text, not a second meaning for the code. The code, status, and param field are unchanged; only the Cause prose is extended to describe both refusals this axis already raises. packages/metadata-protocol was not touched.

Gates

39 commands derived via node scripts/pm/dispatch-gates.mjs --commands content/docs/api/error-catalog.mdx at branch base 77781151d, all run to completion, all passing at head 7f49c35a6 (identical file content between the pre-commit working tree and the commit — no further edits after the gate run):

  • node scripts/check-ci-filter-parity.mjs — 0
  • node scripts/check-closing-keyword-parity.mjs (+ --self-test) — 0 / 0
  • node scripts/check-comment-mask-corpus.mjs — 0
  • node scripts/check-doc-frontmatter.mjs (+ --self-test) — 0 / 0
  • node scripts/check-doc-route-spelling.mjs --advisory / --self-test — 0 / 0
  • node scripts/check-docs-section-name.mjs (+ --self-test) — 0 / 0
  • node scripts/check-section-landing-index.mjs (+ --self-test) — 0 / 0
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions — 0 (after building @objectstack/spec+@objectstack/lint dependency closure through the shared verify lock; first attempt returned PREREQUISITE NOT MET exit 3 pre-build)
  • pnpm --filter @objectstack/lint run check:doc-security-posture — 0 (same prerequisite)
  • pnpm --filter @objectstack/spec run check:docs — 0 (same prerequisite; needs gen:schema's output, produced by the spec build)
  • pnpm --filter @objectstack/spec run check:empty-state — 0
  • pnpm --filter @objectstack/spec run check:liveness — 0
  • pnpm --filter @objectstack/spec run check:skill-examples — 0 (needed @objectstack/client-react built too; first two attempts were PREREQUISITE NOT MET exit 1 for missing .d.ts — built via the shared lock, then green)
  • pnpm --filter @objectstack/spec run check:strictness-ledger — 0
  • pnpm --filter @objectstack/spec run check:variant-docs — 0
  • pnpm --filter @objectstack/spec run check:yaml-examples — 0
  • pnpm check:corpus-claim-drift — 0
  • pnpm check:cross-package-test-inputs — 0
  • pnpm check:doc-anchors — 0
  • pnpm check:doc-authoring — 0
  • pnpm check:docs-audit-scope — 0
  • pnpm check:docs-redirects — 0
  • pnpm check:docs-single-h1 — 0
  • pnpm check:docs-transcript-drift — 0 (same lint-build prerequisite as above)
  • pnpm check:driver-memory-census — 0
  • pnpm check:error-status-conformance — 0
  • pnpm check:nul-bytes — 0 (re-run after commit, at head 7f49c35a6)
  • pnpm check:published-readme-links — 0
  • pnpm check:react-page-adapter-contract — 0
  • pnpm check:refd-timer-probe — 0
  • pnpm check:role-word — 0
  • pnpm check:skill-identifier-liveness — 0
  • pnpm check:vendor-version-stamps — 0
  • pnpm check:watch-hint-literal — 0

TURBO_SCM_BASE="$BASE" pnpm exec turbo ls --affected reports 0 affected packages for this diff (pure content/docs prose, no package build graph edge) — no dependency-closure build was owed for the diff itself; the three builds above were pulled in only as prerequisites of otherwise-unrelated whole-tree doc gates that read compiled dist/, not because this change touches those packages' sources.

Changeset

content/docs/** publishes nothing from any released package → skip-changeset label applied to this PR.


🤖 Generated with Claude Code

https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8


Generated by Claude Code

…hape refusals

The searchFields parenthetical in the INVALID_FIELD Cause only described the
"real field outside the searchable set" refusal. It did not cover the two
shape refusals raised by assertSearchFieldsAreSearchable (an array entry that
is not a string, and a value that is neither a comma-separated string nor an
array) — both of which throw the same code/status/param, just on a different
axis of the value. This is a coverage gap in one clause of the Cause text, not
a second meaning for the code (#15882).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
@baozhoutao baozhoutao added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 6, 2026 — with Claude
@github-actions github-actions Bot added size/xs documentation Improvements or additions to documentation labels Sep 6, 2026
@baozhoutao
baozhoutao marked this pull request as ready for review September 6, 2026 11:43
@baozhoutao
baozhoutao enabled auto-merge September 6, 2026 11:43
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 6, 2026
Merged via the queue into main with commit 2756e07 Sep 6, 2026
37 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-15882-error-catalog-searchfields-shape branch September 6, 2026 12:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

error-catalog.mdx's INVALID_FIELD Cause does not cover the two searchFields SHAPE refusals that raise it

2 participants