You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(data): a filter the server cannot apply is rejected, not silently ignored (#4181) (#4209)
`?filter={status:done` — one missing quote — answered 200 with the UNFILTERED
page. The JSON-parse tolerance (`catch { /* keep as-is */ }`) left the raw
string on `where`, a shape no driver consumes, so the filter was dropped whole
and the response was byte-for-byte a successful unfiltered query. Worst
failure direction in this family: #4134 returned nothing, #4164 dropped one
predicate, this returned everything.
The sibling `GET /data/:object/export` route had rejected the same input since
it was written — the list path was the outlier. The guard moves into the
shared normalizer so the list route, `POST /data/:object/query` and the
runtime dispatcher inherit one answer:
- Unparseable JSON, and JSON that parses to a non-filter (`5`, `"done"`,
`null`) → 400 INVALID_FILTER, stating the filter was NOT applied.
- Blank `?filter=` stays absent, not malformed.
- `filter`/`filters`/`$filter`/`where` are four spellings of one slot;
different values are now 400 INVALID_REQUEST (the request is ambiguous, not
the filter). Identical redundant spellings pass.
- Export's `orderby` gets the same rule, and the test it never had.
Reconciled with #4121, which landed malformed-filter-ARRAY rejection on this
same code path in flight: both halves now share INVALID_FILTER, pinned by a
test that four differently-broken filters produce exactly one wire code.
#4164's `typeof where === 'object'` merge guard — added because this tolerance
could leave a raw string on `where` — is unreachable and removed with it.
Copy file name to clipboardExpand all lines: content/docs/api/data-api.mdx
+19-1Lines changed: 19 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ Query records with filtering, sorting, selection, and pagination.
19
19
|:----------|:---------|:------------|
20
20
|`object`| path | Object name |
21
21
|`select`| query | Comma-separated field names |
22
-
|`filter`| query | Filter expression (JSON). `filters` also accepted for backward compatibility. |
22
+
|`filter`| query | Filter expression (JSON). `filters` also accepted for backward compatibility. Malformed JSON is rejected with `400 INVALID_FILTER` — never ignored. |
**Cause:** The server could not turn the request's filter into something it can
126
+
run. Covers an invalid operator or field in the `where` clause, a `$filter`
127
+
array that is not a filter AST (a bad operator, a lone `["and"]`), a `filter`
128
+
query parameter that is not valid JSON, and JSON that parses to something that
129
+
is not a filter (`5`, `"done"`, `null`).
130
+
**Fix:** Use valid filter operators (`$eq`, `$ne`, `$gt`, `$lt`, `$in`, `$contains`, etc.) and a filter shape the [Data API](/docs/api/data-api) accepts — an object, or an array of `[field, operator, value]` conditions. The `error` message names the offending element.
131
+
**Why it is an error and not an empty result:** a filter the server cannot run
132
+
is never silently skipped, because skipping it would return the **unfiltered**
133
+
result set — a response indistinguishable from a successful query.
0 commit comments