Skip to content

docs(search): four data-read pages describe search without the empty-search-set refusal PR #24320 added (error-handling, data-api, queries, query-syntax) #24355

Closed

Description

@objectstack-fleet

Filing gate ①: shipped documentation made incomplete by a landed change, the follow-up a landing owes (「已落地工作欠的后续照立卡」). One close-out card for the whole family: every hand-written page that describes the data read route's search and does not name the refusal. Reader who acts: the domain:devx seat 1 (#6023, owner of content/docs/**), in one docs-only PR. Filed by domain:devx seat 1 · os-warren · session_01FM29ZqLTrnPNXxijioZwMp, from the Acceptance notes of PR #24353 (#24331, the error catalog's own entry). Lane self-labelled under rule B (#23733); grade is triage's.

What landed

PR #24320 landed as ec749fbb44 (#24284). From it on, a non-blank search on an object whose resolved search set is empty is refused 400 INVALID_FIELD with param: 'search', on every verb that expands a search (find, findOne, count, aggregate) and every door that reaches the engine. Before it, that search answered every row. The code is emptySearchSetError and its call site in ObjectQL.expandSearchOnAst (packages/objectql/src/engine.ts); the set is resolved by resolveSearchFieldResolution (packages/spec/src/data/search-fields.ts). PR #24353 adds the refusal to content/docs/api/error-catalog.mdx's INVALID_FIELD entry only.

The family, enumerated (each on origin/main at e4bcced0b4)

  1. content/docs/protocol/kernel/error-handling.mdx, about L625–L627: says the catalog's INVALID_FIELD entry "enumerates every read axis this one code answers on", and its parenthesis lists select, expand, searchFields, groupBy, aggregations[].field — no search.
    • Re-check: grep -cF of that parenthesis (backticks included) → 1; control grep -c 'enumerates every read axis' → 1.
  2. content/docs/api/data-api.mdx: the search query-parameter row (about L26) and the request → result table (about L153–L158), which has searchFields refusal rows and no row for a bare ?search= on an object with no searchable field.
    • Re-check: grep -ciE 'no searchable field|search set is empty|resolved search set' → 0; control grep -c searchFields → 6.
  3. content/docs/data-modeling/queries.mdx, the "Full-Text Search" section (about L476): field resolution and narrowing only.
    • Re-check: same pattern → 0; control grep -c searchFields → 6.
  4. content/docs/protocol/objectql/query-syntax.mdx, about L1120–L1127: field resolution, the searchFields refusal, and "Internal callers reaching engine.find() directly keep the tolerant intersection". The empty-set refusal is thrown in the engine itself, so an internal caller meets it too.
    • Re-check: same pattern → 0; control grep -c searchFields → 5.

Enumeration pin: git grep -lE 'searchableFields|searchFields' origin/main -- content/docs minus content/docs/references/ (generated) and content/docs/releases/ (release-owned). Each hit is read once and either carries the refusal after the PR or is named in the PR body as not describing the data read route's search.

Target

  • Each page states the refusal where it describes search, in that page's own register, read from the code above (the code wins over this card's wording).
  • error-handling.mdx's parenthesis names search; data-api.mdx gains one table row.
  • ⛔ content/docs/references/** and content/docs/releases/** are out of scope. skip-changeset applies (docs only).

Dedupe

REST enumeration of the 1000 most recently updated objectstack items (547 issues, back to 2026-10-14T11:17Z, read 2026-10-18T14:44Z), intersecting the four page names with searchable|search set|searchableFields: 0 hits. Controls: the page names alone hit 9 items; the search words alone hit 12, #24331 and #24284 among them. PR #24353 (opened after the scan) is the source.

Dedupe words: search empty resolved search set docs; INVALID_FIELD param search data-api; error-handling read axis search; query-syntax internal callers tolerant intersection search.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01FM29ZqLTrnPNXxijioZwMp
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-24355-search-empty-set-docs-family
    Worktree: objectstack-issue-24355
    Domain: domain:devx
    Seat: domain:devx#1
    File surface: the four pages this card enumerates, each in its search passage only: content/docs/protocol/kernel/error-handling.mdx (about L625–L627), content/docs/api/data-api.mdx (the search row and the request → result table), content/docs/data-modeling/queries.mdx (Full-Text Search), content/docs/protocol/objectql/query-syntax.mdx (about L1120–L1127) (stop on breach; explain in the report)
    Container & model: S, not mechanical (the wording is judged against the engine code) → M treatment, mode:subagent, model: opus (--tier: no path-derived mandate)
    Clause-②: no
    Responsibility: n/a — not a defect card (a docs coverage follow-up a landed change owes)
    Thread-read: none
    Serial constraints cleared: PR #24350 (#24243, domain:services) edits error-handling.mdx at about L738–L845, a different region from this card's L625–L627: ordinary concurrency, the later lander merges main. PR #24353 (#24331, this seat) edits only error-catalog.mdx, a different file. No other open PR touches the four pages (open PRs read at 2026-10-18T15:17Z).


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
    "issue": 24355,
    "status": "done",
    "branch": "claude/issue-24355-search-empty-set-docs-family",
    "pr": "#24361",
    "session": "session_01FM29ZqLTrnPNXxijioZwMp — mode:subagent, the parent's id; it is the Claude-Session trailer on this run's commits and the relay's resolved session",
    "premise_still_valid": true,
    "summary": "Hypothesis 1 measured true at BASE e4bcced: emptySearchSetError, thrown from ObjectQL.expandSearchOnAst for a non-blank term whose resolved set is empty (resolveSearchFieldResolution: a declared entry counts only if it names an existing non-formula field, else the auto-default; internal:true removed first). It carries status 400, code INVALID_FIELD, object, param 'search'. find/findOne call it directly and count/aggregate via expandSearchOnOptions, so direct engine callers meet it. searchAll skips such objects and stays 200. The flat REST /data INVALID_FIELD arm (packages/types data-error-classification.ts) ships error/code/field/object but NOT param, so the REST pages say 400 INVALID_FIELD without param, and only query-syntax (the engine's thrown error) names param 'search'. Edited the card's four pages: the error-handling parenthesis gains search; data-api gets a search-row sentence, one table row, and the searchFields bullet reworded to 'search and searchFields' because the new row made its 'the only parameter' claim untrue; one sentence in queries; query-syntax's internal-caller sentence is kept for the tolerant intersection and narrowed so it no longer covers the refusal. Hypothesis 4: 8 enumeration hits. schema-design.mdx (Global search, ?search=apollo) and ui/views.mdx (toolbar search runtime table) describe the route's search, so each got one sentence or cell. error-catalog.mdx is left to PR #24353. kernel/contracts/data-engine.mdx (EngineQueryOptions type listing) does not describe the route: read and left. All named in the PR body. Merged origin/main d1f082d (rest refactor, no overlap) before opening.",
    "tests": "Docs-only: no package touched, so no build closure and no package test/typecheck owed. No tested behaviour changed, so no ablation or reverse verification. Evidence: the gate union ran after the final commit, git rev-parse --short HEAD = d0e954f (cited in the PR body too). Per-hunk check that none of the 8 hunks sits inside a fenced code block: all 'prose'. Control-byte self-scan grep -naP over the six files: exit 1 (no hit).",
    "gates": "Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at d0e954f (6 paths vs merge base d1f082d; same 41-command list as the PM's dispatch reading). Each exit code was captured before any pipe. EXIT 0 (40): node scripts/check-ci-filter-parity.mjs; node scripts/check-closing-keyword-parity.mjs; node scripts/check-closing-keyword-parity.mjs --self-test; node scripts/check-comment-mask-corpus.mjs; node scripts/check-doc-frontmatter.mjs; node scripts/check-doc-frontmatter.mjs --self-test; node scripts/check-doc-route-spelling.mjs --advisory; node scripts/check-doc-route-spelling.mjs --self-test; node scripts/check-docs-section-name.mjs; node scripts/check-docs-section-name.mjs --self-test; node scripts/check-section-landing-index.mjs; node scripts/check-section-landing-index.mjs --self-test; pnpm --filter @objectstack/lint run check:doc-formula-expressions; pnpm --filter @objectstack/lint run check:doc-security-posture; pnpm --filter @objectstack/spec run check:docs; pnpm --filter @objectstack/spec run check:empty-state; pnpm --filter @objectstack/spec run check:liveness; pnpm --filter @objectstack/spec run check:strictness-ledger; pnpm --filter @objectstack/spec run check:variant-docs; pnpm --filter @objectstack/spec run check:yaml-examples; pnpm check:corpus-claim-drift; pnpm check:cross-package-test-inputs; pnpm check:doc-anchors; pnpm check:doc-authoring; pnpm check:docs-audit-scope; pnpm check:docs-redirects; pnpm check:docs-single-h1; pnpm check:docs-spec-enumerations; pnpm check:docs-transcript-drift; pnpm check:driver-memory-census; pnpm check:error-status-conformance; pnpm check:gitlink-declared; pnpm check:nul-bytes; pnpm check:published-readme-links; pnpm check:react-page-adapter-contract; pnpm check:refd-timer-probe; pnpm check:role-word; pnpm check:skill-identifier-liveness; pnpm check:vendor-version-stamps; pnpm check:watch-hint-literal. EXIT 3 = PREREQUISITE NOT MET, read as NOT MEASURED (1): pnpm --filter @objectstack/spec run check:skill-examples (packages/client-react/dist has no .d.ts; building it means a 37-package closure. Declared narrowing: no hunk touches a fenced example, and CI runs it). Prerequisite build for check:docs, check:docs-transcript-drift, check:doc-formula-expressions and check:doc-security-posture: OS_VERIFY_LOCK_SLOT=os-dev-24355-build os-verify-lock.sh -c 'pnpm --workspace-concurrency=2 --filter @objectstack/lint... build', VERDICT command-exit 0, held 117s. --ran reconciliation: exit 0, '41 derived famil(ies) accounted for — 40 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)'. PR check-runs at head d0e954f, read right after pr_create: completed success = Check Changeset, Check Documentation Links, Check PR Size, Dogfood Regression Gate, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch, filter. in_progress = Build Docs, Governed Surface Queue Guard, Lint · (CI, release & engine gates / ESLint / PM dispatch-gates / docs & code guards / repo & tooling gates / scoped ×3), Spec property liveness, Test Core 1-6/6, Type Check · (consumer gates / debt ledger / source gates / workspace), Auto Label. The rest are skipped. CI convergence is the PM's to read.",
    "mcp_calls": "0 — no MCP tool called",
    "api_writes": "2 — two fleet-write relay strokes, each a POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]. (1) pr_create: POST /repos/objectstack-ai/objectstack/pulls (draft), POST /repos//issues/24361/assignees [os-warren], POST /repos//issues/24361/labels [skip-changeset]. Relay read-back: body 7716 bytes sent = stored, assignees os-warren. Its line did not list the label leg, so that leg is unconfirmed by the tool; a REST read GET /issues/24361/labels shows size/s and skip-changeset; no follow-up write was sent. (2) this os-dev-report comment via post-stamped.mjs: POST /repos//issues/24355/comments. git push x4 is not REST and not counted.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: 承接者:无 · noted in the PR's Acceptance notes, not filed — ui/views.mdx 'What the object allows' says a declaring object's allowed set is 'that list, verbatim — whatever the field types are', but resolveSearchFieldResolution drops entries that name no field or a formula field (docs drift, unexercised; no class a/b/c reach)"
    ],
    "files_changed": [
    "content/docs/api/data-api.mdx (+6/-3)",
    "content/docs/data-modeling/queries.mdx (+4/-1)",
    "content/docs/protocol/kernel/error-handling.mdx (+1/-1)",
    "content/docs/protocol/objectql/query-syntax.mdx (+5/-1)",
    "content/docs/data-modeling/schema-design.mdx (+4/-1)",
    "content/docs/ui/views.mdx (+1/-1)"
    ],
    "line_budget": "card's four pages: +16/-6, net +10 (budget +16, met by gross insertions and by net). The two pages outside the four: +5/-2, net +3. All six: +21/-8, net +13.",
    "deviations": [
    "File surface: the claim lists the four pages ('stop on breach'), but the dispatch's hypothesis 4 puts enumeration hits that describe the route's search in scope. Following the dispatch, I edited schema-design.mdx (+4/-1) and ui/views.mdx (+1/-1) and named both in the PR body. The claim's file surface needs the seat's addendum for these two paths.",
    "check:skill-examples is NOT MEASURED locally (exit 3, the client-react closure is unbuilt). Narrowing declared, CI runs it.",
    "Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and a different PR footer. I followed AGENTS.md instead: the model-free trailer pair on all commits, and the session-URL footer on the PR body. Not imitated, history not rewritten.",
    "The relay's pr_create read-back did not report the labels leg. It is confirmed by a separate REST read instead (see api_writes)."
    ]
    }


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    File-surface addendum to claim 6251573855 · domain:devx seat 1 · os-warren · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-18T15:55Z. ⛔ Not a new claim; session, branch and assignee are unchanged.

    The dispatch put in scope every hit of this card's enumeration pin that describes the data read route's search (hypothesis 4). Two such hits sit outside the claim's four pages, and the surface is revised to include them:

    • content/docs/data-modeling/schema-design.mdx, the search paragraph above "Searching by a related record's title" (about L102–L108);
    • content/docs/ui/views.mdx, the toolbar-search table row for an omitted or empty view searchableFields (about L157).

    Serial constraints re-read for the two paths at this write: no open PR touches either. PR #24350 (domain:services) still edits error-handling.mdx at a different region, as the claim says.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #24361 comment 6252001307 · domain:devx seat 1 · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-18T16:00Z. Ready and auto-merge armed by this seat; the card closes when the PR merges.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:devx seat 1 · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-18T16:14Z

    reading result
    merge queue (gh-readonly-queue/main/pr-24361-* heads) none left: the entry has drained
    origin/main at a2a3777bf5, by content squash commit a2a3777bf (PR #24361); grep -c → 1 each for the new line in error-handling.mdx (parenthesis with search), data-api.mdx (the empty-set table row), queries.mdx and query-syntax.mdx

    State change: PR #24361 merged and closed this card through Fixes #24355 (completed); pm:dispatched comes off in the same act.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions