Skip to content

fix(compilers/openapi): report forbidden querystring keywords - #462

Open
fuad-daoud wants to merge 2 commits into
mainfrom
fix/querystring-keyword-report
Open

fix(compilers/openapi): report forbidden querystring keywords#462
fuad-daoud wants to merge 2 commits into
mainfrom
fix/querystring-keyword-report

Conversation

@fuad-daoud

Copy link
Copy Markdown
Collaborator

Summary

OpenAPI 3.2 forbids style, explode and allowReserved at in: querystring: the location binds the whole query string from the parameter's content, so its serialization is stated by the media type and nothing else. The bundled parser enforces only style, and the compiler reported what the parser gave it — so explode and allowReserved reached the IR with nothing said (#408). Keeping them is deliberate and stays: the document states them, and dropping declared content is an emitter's call. The gap was the silence.

The compiler now reports each of the two under a new stable code, openapi/invalid-location-keyword, at the keyword's own pointer, while still lowering the value as declared. It is a warning, not the error style gets: style's finding is the parser's refusal-class validation, whereas this is the compiler keeping a value it lowered and saying so — the same class as reserved-header-name and invalid-method-key beside it — and --fail-on warning lets a user refuse the document. That choice is what keeps both fixtures inside the harness's full sweep (irverify, determinism, order-invariance), where an error would have stopped the oracle at the first diagnostic. ir-design.md's OpenAPI row records the rule beside the in: querystring clause.

The emit site sits in lowerParameter, whose single caller receives every mount — path-item and operation parameters, the 3.2 query method, callbacks — with $ref entries resolved to their target first, so a component parameter reports at /components/parameters/X/explode.

Test plan

  • New conformance case querystring-forbidden-keywords with the issue's two operations: pins the binding still carries explode: false / allowReserved: true and one warning at each keyword's pointer with the exact message. The pre-existing param-querystring.yaml (from openapi: querystring parameters are stamped with a style the spec forbids #334) already declared explode at querystring in anticipation of this issue; its golden gains exactly the one new diagnostic.
  • morphic-harness reports ok on both fixtures; no knownInvalid entries needed.
  • Planting the defect back (removing the emit) reddens four assertions across the conformance and unit tests.
  • make gate passes: lint 0 issues, coverage at 100%, fuzz, bench-smoke.

Closes #408

🤖 Generated with Claude Code

https://claude.ai/code/session_01TJZJ8HaugGZTjzVueafLAT

fuad-daoud and others added 2 commits September 11, 2026 13:44
OpenAPI 3.2 forbids style, explode, and allowReserved at a parameter's
in: querystring — the location binds the whole query string from the
parameter's content, so its serialization is stated by the media type
alone. The bundled parser enforces only the style half of that rule,
so a document declaring explode or allowReserved there reached the IR
with nothing said: the value still lowered as declared (dropping
content the document states is an emitter's call, not a compiler's),
but silently.

Add diag.InvalidLocationKeyword, a new stable code this compiler
reports at the keyword's own pointer with error severity — matching
what the parser already gives style at the same location — whenever
explode or allowReserved is declared at in: querystring. The value
keeps lowering exactly as before; only the diagnostic is new.

A conformance case pins both keywords together, and the existing
param-querystring fixture's already-declared explode now carries the
diagnostic it always should have. Both carry an error diagnostic, so
both move to the harness's known-invalid list, with reasons matching
the entries already there.

Closes #408

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJZJ8HaugGZTjzVueafLAT
Review of the previous commit found that error severity for
diag.InvalidLocationKeyword was the wrong call: unlike style's finding,
which is the parser's own pre-compile refusal, this diagnostic is the
compiler keeping a value it already lowered and saying so — the same
shape as reserved-header-name and invalid-method-key, both warnings.
Switch it to warning, and update its GoDoc to explain that split
instead of claiming all three keywords share one severity.

With the severity fixed, both conformance fixtures pass
TestConformance's ordinary assertNoErrorDiags again, so the
errorCarryingCases() exception this added is no longer needed; removed
it along with its branch in TestConformance. Both fixtures also drop
out of internal/harness/corpus_test.go's knownInvalid list, restoring
that file to its pre-existing form, and go run ./cmd/morphic-harness
now reports "ok" on both — back in the irverify/determinism/
order-invariance sweep rather than stopped at the first error.

Regenerated both conformance goldens; the only change in either is the
diagnostics' severity field. Split the ir-design OpenAPI row's
querystring clause so it no longer reads as if style shared the new
code, and trimmed the #408 rationale out of the test GoDocs that had
started repeating it, leaving diag.go's GoDoc as the one place it lives.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJZJ8HaugGZTjzVueafLAT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

openapi: explode and allowReserved at in: querystring are kept in silence

1 participant