Repository navigation
sentry api silently drops repeated -F flags on GET requests #1476
Description
What happened
sentry api lets you pass multiple -F key=value flags to select several columns, tags, or fields on a GET request. In practice only the last one survives — every earlier -F with the same key is silently overwritten, with no error or warning. The request goes out with far fewer parameters than the command line implies, and the resulting failure looks completely unrelated to a dropped CLI flag.
This is confusing for a human or an agent following the CLI's own -F key[]=value "array append" help text, because that syntax is real for POST/PUT JSON bodies but does nothing useful for GET query strings — it gets passed through literally as a query key named field[].
Why this is confusing in practice
Two real examples where this cost debugging time:
- Selecting multiple log columns with
-F 'field[]=timestamp' -F 'field[]=message' -F 'field[]=tags[shard_id,number]'against thelogsdataset returned500 Internal error. Please try again.It looked like the dataset didn't support multi-column or custom-tag selection at all. In reality only the last field was ever sent (the dry-run URL showed a singlefield%5B%5D=...), so Snuba rejected the under-specified request several layers downstream. Only inspecting--dry-runoutput revealed the missing fields. - Combining
-F 'field=timestamp' -F 'sort=-timestamp'returned"orderby must also be in the selected columns or groupby"even thoughtimestampwas clearly on the command line. The apparent bug looked like broken sort validation — but an earlier repeated-F field=...key had already silently overwritten itself, so the actual selected-columns list sent to the server didn't match what the command line implied.
In both cases the failure surfaces as an opaque server-side error several layers away from the real cause (a CLI flag silently dropped on the client), so the natural next debugging step — "this dataset/parameter must be unsupported" — is wrong and wastes time. Switching from -F to -f (raw field, no JSON parsing) fixed both cases, since -f already merges repeats into an array.
Root cause
Root cause is in packages/cli/src/commands/api.ts:
buildQueryParams()(used for-F key=valueon GET requests) never merges repeated identical keys into an array — each call just doesresult[key] = value, so only the last-F field=xsurvives. This differs frombuildRawQueryParams()(-f), which already merges repeats intostring[].- Bracket-array syntax (
key[]=value, documented in the-Fhelp text as"Array append: {key: [value]}") is only implemented for the JSON-body path (parseFields/setNestedValue, used for POST/PUT). For GET requests,key[]is passed through literally as the string"field[]"with no stripping or special handling. - The only tested way to send a multi-value GET param today is a single
-F 'field=["a","b"]'JSON-array value (seepackages/cli/test/commands/api.test.ts).
Net effect: sentry api ORG/PROJECT/events/ -F field[]=timestamp -F field[]=message (or repeating -F field=x without brackets) silently sends a single query param literally named field[] with only the last value — not field=timestamp&field=message. Downstream, Sentry's Django request.GET.getlist("field") never matches field[], so the request resolves to zero selected columns. Against the ourlogs/logs dataset this surfaced as an opaque 500 Internal error. Please try again. (tracked separately in getsentry/sentry as SnubaRPCError: code: 400 — At least one column must be specified in the request, sentry.sentry.io issue 6683878692).
The -F help text presents key[]=value as a uniform rule for all requests, with no callout that it only applies to JSON request bodies, not GET query strings.
Proposed fixes
- Make
buildQueryParams()merge repeated identical-F field=xvalues into a real array/repeated query param, matchingbuildRawQueryParams()'s existing behavior. - Either support
key[]=valuebracket syntax for GET query building (stripping the brackets and merging into a repeat), or make it a validation error with a clear message instead of silently producing a mismatched literalfield[]param. - Update the
-F/--fieldhelp text to clarify thatkey[]=valuearray-append semantics are body-only; document the correct GET multi-value syntax (repeat-F field=x, or a JSON-array value).
via lorenzo.
--
Activity
[-]`sentry api` GET requests silently drop repeated/bracket `-F field=` values[/-][+]sentry api silently drops repeated -F flags on GET requests[/+]linear-code commentedon Oct 12, 2026
MCP-1069