Skip to content

fix: a request asks for a representation the server can produce - #122

Merged
ShocOne merged 1 commit into
mainfrom
fix/a-request-asks-for-a-representation-the-server-can-produce
Aug 26, 2026
Merged

fix: a request asks for a representation the server can produce#122
ShocOne merged 1 commit into
mainfrom
fix/a-request-asks-for-a-representation-the-server-can-produce

Conversation

@ShocOne

@ShocOne ShocOne commented Aug 26, 2026

Copy link
Copy Markdown
Member

The defect

kiota builds a request's Accept header from the media types an operation's responses declare, and reaches the error responses when no success response offers one. An operation answering 204 therefore sends:

Accept: application/problem+json

ThousandEyes refuses that before serving the request:

HTTP 406
{"detail":"Acceptable representations: [application/hal+json, application/json].",
 "title":"Not Acceptable"}

Reproduced against the live API with curl: Accept: application/problem+json → 406, Accept: application/json → 204. The API itself is well behaved — DELETE 204, GET-after-delete 404, second DELETE 404.

Reproduced in kiota 1.34.1 from a 20-line OpenAPI document, so this is generator behaviour and not one document's mistake.

Why it went unnoticed

tag — the only test that was passing — passes by accident. Its DELETE declares application/json on the 500 response, so the union kiota builds happens to contain a type the server can produce:

operation 401/403/404/429 500 Accept emitted result
tag delete problem+json application/json application/json, application/problem+json 204
credential delete problem+json problem+json application/problem+json 406

27 of the 35 pilot resources sent an error-only Accept on DELETE, and 44 of 327 Accept headers across the generated SDK. Every one of those tests would have failed at destroy however well its create worked.

The fix

A fifth Prenormalize pass. An operation whose success responses declare no media type has the content of its error responses dropped, so kiota emits no Accept header — which is correct for a response with no body.

The response is inlined rather than the shared component stripped: one component answers many operations, and those whose success response does declare a media type still need it. Only the description survives, which is the one member a Response Object must carry.

The error mappings the content also generates go with it. That costs the provider nothing: extract_kiota.go reads GetStatusCode() and Error(), which kiota's untyped ApiError carries as well as a typed one.

Measured

Error-only Accept headers in the regenerated pilot SDK: 44 → 0. Total Accept headers 327 → 281; tag's GET still carries application/hal+json, application/json, and the shared component is untouched.

Benchmark (sh tf_acceptance_tests.sh): credential went from Delete failed (HTTP 406) to passing. Full-suite number is in the thread below.

Also in this PR

The Prenormalize doc comment is rewritten to docs/comment-style.md: one paragraph per pass saying what it does and the generator behaviour it answers, with the run-specific measurement ("roughly one generation in five") and the editorial asides removed.

Verification

make check (90.7% total, sdkgen 88.4%) and golangci-lint run (0 issues). Both new tests were confirmed to fail with the pass disabled. The pilot regenerates and postcheck passes.

🤖 Generated with Claude Code

kiota builds a request's Accept header from the media types an operation's
responses declare, and reaches the error responses when no success response
offers one. An operation answering 204 therefore sends
Accept: application/problem+json, and a server that produces that
representation only when refusing answers 406 before serving the request.

Prenormalize gains a fifth pass: an operation whose success responses declare
no media type has the content of its error responses dropped, so no Accept
header is built. The response is inlined rather than the shared component
stripped, because one component answers many operations and those whose
success response does declare a media type still need it.

The error mappings the content also generates go with it, and cost the
provider nothing: the generated error handling reads a status code and a
message, which kiota's untyped error carries as well as a typed one.

Also rewrites the Prenormalize doc comment to docs/comment-style.md: one
paragraph per pass stating what it does and the generator behaviour it
answers, with the run-specific measurement and the editorial asides removed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ShocOne
ShocOne merged commit 29b2810 into main Aug 26, 2026
2 checks passed
@ShocOne
ShocOne deleted the fix/a-request-asks-for-a-representation-the-server-can-produce branch August 26, 2026 14:17
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.

1 participant