Skip to content

Commit 6fb2ea3

Browse files
committed
docs(api): document the repeated-filter refusal on GET /data/:object
`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
1 parent 37b82ed commit 6fb2ea3

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

content/docs/api/data-api.mdx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Query records with filtering, sorting, selection, and pagination.
1919
|:----------|:---------|:------------|
2020
| `object` | path | Object name |
2121
| `select` | query | Comma-separated field names. Every name must exist — an unknown one is `400 INVALID_FIELD`, never dropped. |
22-
| `filter` | query | Filter expression (JSON). `filters` also accepted for backward compatibility. Malformed JSON is rejected with `400 INVALID_FILTER` — never ignored. |
22+
| `filter` | query | Filter expression (JSON). `filters` also accepted for backward compatibility. Malformed JSON is rejected with `400 INVALID_FILTER` — never ignored; so is sending the parameter more than once (`?filter=…&filter=…`), which is refused as a repetition rather than diagnosed as malformed. |
2323
| `sort` | query | Sort expression (e.g. `name asc` or `-created_at`). Must name a real field on the object itself — an unknown name or a dotted path (`account.company_name`) is `400 INVALID_SORT`. |
2424
| `top` | query | Max records to return. No default — omitting it returns all matching records. |
2525
| `skip` | query | Offset |
@@ -76,9 +76,18 @@ successful query:
7676
| `?filter=5`, `?filter="done"`, `?filter=null` | `400` — parses, but is not a filter |
7777
| `?filter=` (blank) | treated as absent — no filter, no error |
7878
| `where` and `filter` sent with **different** values | `400` — aliases for one slot; send exactly one |
79+
| `?filter={"a":1}&filter={"b":2}` — one spelling sent **twice** | `400``Repeated "filter" query parameter — send exactly one` |
7980

8081
The same rule applies to `orderby` on `GET /data/:object/export`.
8182

83+
Sending one spelling **twice** — on `GET /data/:object`, in any of the four
84+
spellings — is refused as its own named cause rather than reported as a
85+
malformed filter: a repeat is neither merged nor resolved by precedence,
86+
because either would apply a filter you did not express. Repetition is counted,
87+
not compared, so two identical occurrences are still two occurrences, while a
88+
single occurrence that a server adapter delivers as a one-element array is
89+
still one.
90+
8291
#### Nor is a sort, a projection, or an expansion
8392

8493
`filter` is not the only parameter that names a field. `sort`, `select` and

0 commit comments

Comments
 (0)