Skip to content

A repeated ?filter= answers two different error codes depending on which data route received it #8001

Description

@hotlong

Found while implementing #7390 (PR pending). Filed unassigned per Prime Directive #10; not fixed there, because #7390's ruling names the code for its own route and the sibling route is a different surface.

The divergence

Two sibling routes in packages/rest/src/rest-server.ts both refuse a repeated ?filter=, and they answer differently:

routecodeenvelopegate
GET /data/:objectINVALID_FILTERflat { error, code, object } (mapDataError)assertFilterParamSuppliedOnce (#7390)
GET /data/:object/exportVALIDATION_ERRORnested { error: { code, message } }refuseRepeatedQueryParams (#6877)

So ?filter=a&filter=b is one caller mistake with two machine-readable answers, decided by which path it was sent to. A client that branches on error.code has to know both.

Why each is currently right on its own terms

Neither is an oversight, which is why this is a fork rather than a bug with an obvious fix:

Both rules are "one condition, one answer" — they just draw the condition's boundary differently. The list route reads it as the filter slot failed; the export route reads it as a single-valued parameter was repeated.

The options, if this is worth closing

  1. Move the export route's filter slot onto the same gate — repeated filter there becomes INVALID_FILTER too, and the other export parameters (format, limit, page, orderby, search, header) keep VALIDATION_ERROR. Consistent per-slot; splits the export route's own answer across two codes.
  2. Leave it. The boundary really is per-route-family, and each envelope matches the family its route already speaks.
  3. Move the list route onto VALIDATION_ERROR — consistent per-condition, but it contradicts the 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 ruling and would give one slot two codes on one route.

Not obviously worth paying for; recording it so the next person to touch either gate is choosing rather than discovering.

Dedup

Searched open issues for repeated-filter / VALIDATION_ERROR / INVALID_FILTER / error-code-inconsistency wording, and for the query-multiplicity and refuseRepeatedQueryParams identifiers. Hits: #7390 (the parent this came out of), #7534, #4436, #3948 — none covers the cross-route code divergence.


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions