Skip to content

Qualify external header schema refs in generated response headers#2463

Merged
mromaszewicz merged 1 commit into
mainfrom
fix/issue-2060
Jul 13, 2026
Merged

Qualify external header schema refs in generated response headers#2463
mromaszewicz merged 1 commit into
mainfrom
fix/issue-2060

Conversation

@mromaszewicz

Copy link
Copy Markdown
Member

Closes: #2060

When a response header is an external $ref (it lives in another file mapped via import-mapping) and that header's schema is itself a $ref to a named type, the generated response-headers struct referenced the type by a bare local name (e.g. ETag ETagSchema) instead of the imported one (ETag externalRef0.ETagSchema). Because the named type is only generated into the imported package, the referencing package failed to compile with an undefined ETagSchema.

The header's schema $ref is written relative to the external file (e.g. #/components/schemas/ETagSchema), so GenerateGoSchema resolves it against the root spec as a bare local name. Since the header component carries its own $ref telling us which file it came from, qualify the schema with that external package via ensureExternalRefsInSchema, mirroring how response content schemas are already handled. This is guarded on the schema being a reference so an external header with an inline primitive schema (e.g. type: string) is not mangled into externalRef0.string.

The fix corrects both the strict-server <Op><Status>ResponseHeaders struct and the client response wrapper's header fields introduced in #2462.

Adds internal/test/references/multipackage/header_ref exercising an external header ref with a ref'd schema across strict-server and client generation; the committed generated files must compile as part of the test module, which guards against the undefined-symbol regression.

Closes: #2060

When a response header is an external `$ref` (it lives in another file
mapped via import-mapping) and that header's schema is itself a `$ref`
to a named type, the generated response-headers struct referenced the
type by a bare local name (e.g. `ETag ETagSchema`) instead of the
imported one (`ETag externalRef0.ETagSchema`). Because the named type is
only generated into the imported package, the referencing package failed
to compile with an undefined `ETagSchema`.

The header's schema `$ref` is written relative to the external file
(e.g. `#/components/schemas/ETagSchema`), so `GenerateGoSchema` resolves
it against the root spec as a bare local name. Since the header component
carries its own `$ref` telling us which file it came from, qualify the
schema with that external package via `ensureExternalRefsInSchema`,
mirroring how response content schemas are already handled. This is
guarded on the schema being a reference so an external header with an
inline primitive schema (e.g. `type: string`) is not mangled into
`externalRef0.string`.

The fix corrects both the strict-server `<Op><Status>ResponseHeaders`
struct and the client response wrapper's header fields introduced in
#2462.

Adds internal/test/references/multipackage/header_ref exercising an
external header ref with a ref'd schema across strict-server and client
generation; the committed generated files must compile as part of the
test module, which guards against the undefined-symbol regression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mromaszewicz
mromaszewicz requested a review from a team as a code owner July 13, 2026 15:28
@mromaszewicz mromaszewicz added the bug Something isn't working label Jul 13, 2026
@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes a compile error in generated code when a response header is an external $ref and its schema is itself a $ref to a named type: the schema type was emitted as a bare local name (e.g. ETagSchema) rather than the imported-package-qualified form (externalRef0.ETagSchema). The one-line fix in GenerateResponseDefinitions calls the existing ensureExternalRefsInSchema helper (already used for response content schemas) on the header schema, guarded on the schema being a reference to avoid qualifying inline primitive types.

  • pkg/codegen/operations.go: After generating the Go schema for each response header, if the header itself is an external $ref and its schema is also a $ref, ensureExternalRefsInSchema is called with the header's ref to qualify the schema type with the imported package name — mirroring the existing pattern applied to response content schemas.
  • internal/test/references/multipackage/header_ref/: New multi-file regression test under the correct references/ category exercising the failing scenario across both strict-server response headers structs and client response wrapper headers. The committed generated files must compile as part of the test module, which is the primary regression guard.

Confidence Score: 4/5

Safe to merge; the change is a narrow, well-scoped fix to a compile-time regression with a compile-time regression test.

The fix is minimal, mirrors an identical pattern already in the codebase for response content schemas, and is guarded against mangling inline primitive types. The generated output compiles correctly and the new test directly exercises the previously failing case for both strict-server and client codepaths. Only a style observation about the test file name keeps this from being a clean pass.

No files require special attention; the only note is the test file name issue_test.go vs the conventional header_ref_test.go.

Important Files Changed

Filename Overview
pkg/codegen/operations.go Targeted fix: qualifies external header schema refs with the imported package name, mirroring the existing pattern for response content schemas. Logic is sound and well-guarded.
internal/test/references/multipackage/header_ref/gen/api/api.gen.go Generated file shows the fix working correctly: both GetThing200ResponseHeaders and GetThingResponse200Headers use *externalRef0.ETagSchema instead of the previously undefined bare *ETagSchema.
internal/test/references/multipackage/header_ref/gen/common/common.gen.go Generated common package correctly emits type ETagSchema = string, which the api package then references via the qualified externalRef0.ETagSchema.
internal/test/references/multipackage/header_ref/issue_test.go Regression test covering both the strict-server response headers struct and the client response wrapper. File is named issue_test.go rather than the conventional header_ref_test.go.
internal/test/references/multipackage/header_ref/spec.yaml New spec exercising an operation whose 200 response carries an ETag header that is an external $ref, exactly the failing scenario from issue-2060.
internal/test/references/multipackage/header_ref/common/spec.yaml Common spec defining the ETag header component whose schema is a $ref to a named type, providing the cross-package reference scenario under test.
internal/test/references/multipackage/header_ref/doc.go Standard doc.go with go:generate directives for both the common and api packages; correctly follows multi-config layout convention.
internal/test/references/multipackage/header_ref/config.api.yaml API generation config enabling chi-server, strict-server, client, and models with the correct import-mapping for the common package.
internal/test/references/multipackage/header_ref/config.common.yaml Common package config generating only models, which is the correct minimal config for the shared schema package.
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
internal/test/references/multipackage/header_ref/issue_test.go:1
**Test file naming inconsistency**

The repository convention for leaf test directories is `<name>_test.go` (matching the directory's snake_case name). This file is `issue_test.go` rather than the expected `header_ref_test.go`. The neighbouring `response_cast` subdirectory also uses `issue_test.go`, so this isn't unique to this PR, but it makes it harder to correlate test files with their scenario directory at a glance.

Reviews (1): Last reviewed commit: "Qualify external header schema refs in g..." | Re-trigger Greptile

@mromaszewicz
mromaszewicz merged commit 1e31932 into main Jul 13, 2026
29 checks passed
@mromaszewicz
mromaszewicz deleted the fix/issue-2060 branch July 13, 2026 16:14
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.

External references are not dereferenced in header->schema

1 participant