Skip to content

fix(compilers/openapi): detect a version key past the sniff cap - #435

Merged
fuad-daoud merged 1 commit into
mainfrom
stack/1-detection
Sep 9, 2026
Merged

fix(compilers/openapi): detect a version key past the sniff cap#435
fuad-daoud merged 1 commit into
mainfrom
stack/1-detection

Conversation

@fuad-daoud

@fuad-daoud fuad-daoud commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Closes #420. Not breaking.

Stripe's published spec3.json — valid OpenAPI 3.0 — was rejected as engine/unrecognized-format because detection sniffed only the first 64 KiB looking for a top-level openapi key, and Stripe puts a multi-megabyte components object first. openapi lands at byte 2,593,401.

The 64 KiB prefix scan stays as the fast path, extracted unchanged into sniffPrefix. When the prefix declares neither openapi nor swagger, a cheap whole-source byte scan decides whether the document is worth reading whole. A source of another format still gets the fast path's silence — detect.go's rule that this compiler must never claim or complain about another format's bytes is preserved.

Verified end-to-end, not just at Detect: a synthetic 279 KB spec with openapi at byte 279,062 goes exit 1exit 0 through the real CLI.

Read this together with stack PR 7, which fixes the defects later reviews found in this commit: the whole read swallowed the flow decoder's error (so the fix missed malformed JSON — valid JSON, the motivating Stripe case, worked here from the start), the key scan was not top-level-scoped, and detection parsed the whole document to find one key, which PR 7 replaces with a scan that reads the version beside it. They are in PR 7 rather than here because that is where they sit in history, and reordering would cost the gate verification each commit already carries.


Stack 1 of 8. Base main — review and merge bottom-up. Every commit here passed make gate when it landed, and the full gate was re-run on the top of the stack. Run it as GOTOOLCHAIN=go1.26.3 make gate; this machine's Go 1.27 fails it for reasons unrelated to any change (#431).

🤖 Generated with Claude Code

https://claude.ai/code/session_01SYeBgDsskwnyitLgPGCPn1

Detect capped its search for `openapi`/`swagger` at the first 64 KiB, so a
valid document that writes a large object before its version key was reported
as an unrecognized format. Stripe's published spec3.json is one: `components`
runs to megabytes and `openapi` lands at byte 2,593,401. Mapping key order
carries no meaning, so the same document with its keys the other way round
compiled fine — the format answer depended on where a writer put a key.

The 64 KiB prefix keeps its place as the fast path, and every document that
declares a key there is still answered without a full parse. When the prefix
declares neither key, a byte scan of the whole source decides whether to read
it whole: only bytes that name `openapi:` or `swagger:` as a top-level key
reach the parse, so a source of another format still gets the fast path's
silence and never a complaint from this compiler.

That scan is what Detect already used to tell its own broken source from
another format's, and it is no longer bounded to the prefix either. A document
whose prefix does not parse and whose declaration sits past the cap is now
reported as an undecodable OpenAPI source rather than declined, which is the
answer the surrounding rule always intended; detection now reads the bytes it
would have had to read to say otherwise.

Fixes #420

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SYeBgDsskwnyitLgPGCPn1

@Wahbeh-Mohammad Wahbeh-Mohammad left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked by running the code, not just reading it. The Stripe case works: real spec3.json goes from exit 1 on main to exit 0 here. One correction to the body: the note that the fix "missed JSON" is wrong, JSON is the case that works.

Four comments inline: the unbounded whole-file parse, other formats' files getting claimed, tests that stay green with the logic broken, and key order still deciding the result when both keys are present.

Comment thread compilers/openapi/detect.go
Comment thread compilers/openapi/detect.go
Comment thread compilers/openapi/detect_test.go
Comment thread compilers/openapi/detect.go
@Wahbeh-Mohammad

Copy link
Copy Markdown

Review done by me + fable

@fuad-daoud fuad-daoud assigned fuad-daoud and unassigned OmarAlJarrah Sep 9, 2026
@fuad-daoud
fuad-daoud merged commit 49ad4be into main Sep 9, 2026
1 check passed
@fuad-daoud
fuad-daoud deleted the stack/1-detection branch September 9, 2026 19:40
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.

Format detection misses openapi past 64 KiB: Stripe's published spec is rejected

3 participants