Skip to content

docs(api): document the repeated-filter refusal on GET /data/:object - #8142

Merged
hotlong merged 1 commit into
mainfrom
claude/issue-8005-data-api-repeated-filter-doc
Aug 12, 2026
Merged

docs(api): document the repeated-filter refusal on GET /data/:object#8142
hotlong merged 1 commit into
mainfrom
claude/issue-8005-data-api-repeated-filter-doc

Conversation

@hotlong

Copy link
Copy Markdown
Contributor

Fixes#8005

content/docs/api/data-api.mdx is the page that documents the filter query parameter and its rejection behaviour specifically, but it named only one cause of 400 INVALID_FILTER: malformed JSON. PR #8004 (#7390) shipped a second cause on the same slot — sending one spelling more than once — and the page never caught up.

The page was incomplete, not wrong. Nothing there claimed malformedness was the only cause, so the malformed-JSON sentence at :22 and the drop-vs-fail reasoning at :68 are both left standing; the new cause is added alongside them.

What changed

Docs-only, one file, 10 insertions / 1 deletion.

  1. The filter table row now names repetition next to malformed JSON, and says it is refused as a repetition rather than diagnosed as malformed — which is the point of finding: a repeated ?filter= on GET /data/:object cannot be told from a filter AST, so it is diagnosed as a malformed filter (and, rarely, succeeds) #7390 rather than a wording preference.
  2. The "a filter either applies or fails" table gains a row for one spelling sent twice, quoting the shipped message verbatim: Repeated "filter" query parameter — send exactly one.
  3. One paragraph after that table carries the two contract facts a caller cannot guess:
    • a repeat is neither merged nor resolved by precedence, because either would apply a filter you did not express (the maintainer's 2026-08-11 ruling, as the shipped message states it);
    • repetition is counted, not compared — two identical occurrences are still two, while a single occurrence a server adapter delivers as a one-element array is still one.

Written from the source, not from the card

Every claim was read off packages/rest/src/query-multiplicity.ts on main, not paraphrased:

  • the message text from repeatedFilterParamMessage() (:191);
  • the envelope (400 / INVALID_FILTER, flat mapDataError body) from assertFilterParamSuppliedOnce() and the assertions in rest-server-repeated-filter-param.test.ts;
  • the count-not-shape rule and the one-element-array unwrap from readSingleQueryValue() and the preservation cases in that same test.

⚠️ Note for anyone verifying this: the message is templated, so grepping the rendered string Repeated "filter" returns zero hits and reads as "the feature is absent". Grep the identifier (repeatedFilterParamMessage), not the message.

Judgment call: naming one spelling or all four

The gate is generic over all four wire spellings — where / filter / filters / $filter, confirmed as FILTER_SLOT_QUERY_PARAMS composed from the spec's RPC_QUERY_ALIAS_SLOTS (where + alias filter) plus the two wire-only spellings.

I named filter alone in the table row, whose subject isfilter, and carried the generality in the prose paragraph instead — the section it sits in already opens by declaring the four spellings to be one slot, so restating the list in the row would duplicate a fact the page states 45 lines below. The paragraph says "in any of the four spellings" and points at that existing sentence rather than competing with it.

Also deliberately scoped: the paragraph names GET /data/:object, because assertFilterParamSuppliedOnce has exactly one call site and the export route's orderby is not covered by it. It is placed after the pre-existing "the same rule applies to orderby" line so that sentence keeps its original antecedent.

Verification

No code changed, so there is nothing to test; the docs gates are the verification. All green locally, run against the actual changed path after re-deriving with node scripts/pm/dispatch-gates.mjs content/docs/api/data-api.mdx:

gateresult
check:nul-bytespass
check:doc-authoringpass — 375 files clean
check:doc-anchorspass — 210 fragment links resolve
check:docs-audit-scopepass — 179 hand-written docs in sync
check:quick-reference-countspass
check:role-wordpass
check:doc-formula-expressionspass

The last four were not in the dispatch prompt's list; the re-derivation surfaced them and they are reported here for that reason.

Labels and scope

skip-changeset — docs ship in no published package.

⛔ No packages/** in this diff: the code is correct and shipped, and this is prose catching up to it.

Sibling findings referenced but not addressed here — out of scope: #8001, #8002, #8003. #7967 remains open: this card re-witnesses the same docs-drift blindness (the checker maps docs to packages by textual mention, so a page describing a package's behaviour without naming it is invisible), and the triage comment already recorded it there rather than filing a new card.


Generated by Claude Code

`content/docs/api/data-api.mdx` documents the `filter` parameter's rejection
behaviour, but named only malformed JSON as a cause of `400 INVALID_FILTER`.
PR #8004 (#7390) shipped a second cause on the same slot: sending one spelling
more than once. The page was incomplete, not wrong — the malformed-JSON
sentence stays as it was.
- the `filter` table row now names repetition alongside malformed JSON
- the "a filter either applies or fails" table gains the repetition row,
quoting the shipped message from `repeatedFilterParamMessage()`
- one paragraph carries the shipped reasoning: a repeat is neither merged nor
resolved by precedence, and repetition is counted rather than compared, so a
one-element array from a repeat-preserving adapter is still one occurrence
Docs-only; no published package changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BgZEGQqkLtHZBKrP2ceDwA
@vercel

vercelBot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 12, 2026 5:52pm

Request Review

@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation labels Aug 12, 2026
@hotlonghotlong added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 12, 2026 — with Claude
@hotlong
hotlong marked this pull request as ready for review August 12, 2026 18:19
@hotlong
hotlong added this pull request to the merge queueAug 12, 2026
Merged via the queue into main with commit 7c21fb2Aug 12, 2026
25 checks passed
@hotlong
hotlong deleted the claude/issue-8005-data-api-repeated-filter-doc branch August 12, 2026 18:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: data-api.mdx documents filter's rejection behaviour but not the repetition refusal PR #8004 adds

2 participants

@hotlong@claude