Skip to content

Stringify non-string text/plain responses in strict servers#2464

Merged
mromaszewicz merged 1 commit into
oapi-codegen:mainfrom
mromaszewicz:fix/issue-1897
Jul 13, 2026
Merged

Stringify non-string text/plain responses in strict servers#2464
mromaszewicz merged 1 commit into
oapi-codegen:mainfrom
mromaszewicz:fix/issue-1897

Conversation

@mromaszewicz

Copy link
Copy Markdown
Member

Closes: #1897

For a text/plain response whose schema is not a string, the strict server generated an invalid body conversion in the response Visit method. On the net/http path it emitted w.Write([]byte(response)), which fails to compile for a non-string underlying type (integer, boolean, openapi_types.File). On the fiber/iris/fiber-v3 path it emitted ctx.WriteString(string(response)), which compiles for an integer but silently produces the Unicode code point for that value (e.g. string(201) yields "É") and trips a go vet warning. Only a plain string schema worked.

Wrap the response value in fmt.Sprint so any primitive is rendered as its natural text form: strings pass through unchanged (byte-identical output), integers/booleans/floats render as their literal representation. This mirrors how response headers are already stringified. goimports adds the fmt import as needed.

Adds internal/test/bodies/content_types/text_non_string exercising integer, boolean, and string text/plain responses with runtime assertions that the integer response writes "201" and the boolean writes "true"; regenerates the strict-server fixtures, whose string text responses are unaffected at runtime.

@mromaszewicz mromaszewicz added the bug Something isn't working label Jul 13, 2026
@mromaszewicz
mromaszewicz requested a review from a team as a code owner July 13, 2026 16:50
@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a code generation bug where text/plain responses with non-string schemas (integer, boolean) produced invalid or silently wrong Go code in strict server Visit* methods. All four strict-server templates now use fmt.Sprint(response) instead of []byte(response) / string(response), mirroring how response headers were already stringified.

  • All strict-server template backends updated consistently (net/http, fiber v2, fiber v3, iris); all affected *.gen.go fixtures regenerated.
  • New test leaf internal/test/bodies/content_types/text_non_string/ added under the correct bodies/ category with runtime assertions covering integer, boolean, and string responses on the stdhttp, fiber (v2), and iris paths.
  • fmt.Sprint on an existing string-kinded type is byte-identical, so there is no behavioral regression for any already-working downstream user.

Confidence Score: 5/5

Safe to merge — the fix is a targeted one-line change per template, all fixtures have been regenerated consistently, and runtime tests cover the previously-broken integer and boolean paths on three backends.

The template change replaces an expression that either failed to compile or silently produced wrong output with one that is correct for all primitive types and byte-identical for strings. Every strict-server *.gen.go fixture was regenerated. New regression tests with explicit body-content assertions were added for stdhttp, fiber, and iris. No configuration structs, public API signatures, or serialization wire formats were altered.

No files require special attention.

Important Files Changed

Filename Overview
pkg/codegen/templates/strict/strict-interface.tmpl Core template fix: replaces []byte(response) with []byte(fmt.Sprint(response)) for text/plain responses on the net/http path, correctly handling non-string schemas
pkg/codegen/templates/strict/strict-fiber-interface.tmpl Same fix applied to fiber (v2) template: string(response)fmt.Sprint(response) in ctx.WriteString call
pkg/codegen/templates/strict/strict-fiber-v3-interface.tmpl Same fix applied to fiber v3 template, consistent with v2 change
pkg/codegen/templates/strict/strict-iris-interface.tmpl Same fix applied to iris template: string(response)fmt.Sprint(response) in ctx.WriteString call
internal/test/bodies/content_types/text_non_string/text_non_string_test.go New regression tests covering integer ("201"), boolean ("true"), and string ("pong") text/plain responses on the std-http path
internal/test/bodies/content_types/text_non_string/fiber/fiber_test.go Fiber (v2) path regression test asserting integer 201 serializes as "201" not a Unicode code point
internal/test/bodies/content_types/text_non_string/iris/iris_test.go Iris path regression test asserting integer 201 serializes as "201" not a Unicode code point
internal/test/bodies/content_types/text_non_string/spec.yaml New OpenAPI spec with three /ping responses covering string, integer, and boolean text/plain schemas; correctly placed under bodies/content_types/
internal/test/servers/strict/fiber/server.gen.go Regenerated fixture updated consistently: four text/plain Visit* methods now use fmt.Sprint; changes are scoped to string-kinded responses so runtime behavior is unchanged
internal/test/bodies/responses/headers/headers.gen.go Regenerated: response.Body (a string) now wrapped in fmt.Sprint — semantically identical for string types, no behavioral change

Reviews (2): Last reviewed commit: "Stringify non-string text/plain response..." | Re-trigger Greptile

Closes: oapi-codegen#1897

For a `text/plain` response whose schema is not a string, the strict
server generated an invalid body conversion in the response `Visit`
method. On the net/http path it emitted `w.Write([]byte(response))`,
which fails to compile for a non-string underlying type (integer,
boolean, `openapi_types.File`). On the fiber/iris/fiber-v3 path it
emitted `ctx.WriteString(string(response))`, which compiles for an
integer but silently produces the Unicode code point for that value
(e.g. `string(201)` yields "É") and trips a `go vet` warning. Only a
plain `string` schema worked.

Wrap the response value in `fmt.Sprint` so any primitive is rendered as
its natural text form: strings pass through unchanged (byte-identical
output), integers/booleans/floats render as their literal
representation. This mirrors how response headers are already
stringified. `goimports` adds the `fmt` import as needed.

Adds internal/test/bodies/content_types/text_non_string exercising
integer, boolean, and string text/plain responses with runtime
assertions that the integer response writes "201" and the boolean
writes "true"; regenerates the strict-server fixtures, whose string text
responses are unaffected at runtime.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mromaszewicz
mromaszewicz merged commit 18ef715 into oapi-codegen:main Jul 13, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invalid Code Generation for Responses with Content Type "text/plain"

1 participant