Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: oapi-codegen/oapi-codegen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: oapi-codegen/oapi-codegen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: type-name-default
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 10 commits
  • 24 files changed
  • 3 contributors

Commits on Feb 27, 2026

  1. feat: multi-pass type name resolution

    I've been meaning to use this approach for a long time, because
    the attempts at avoiding type collisions via structure suffixes or
    prefixes work sporadically, at best.
    
    Conflict resolution is fundamentally a global problem, not a local
    problem when doing recursive traversal, so this PR splits the code
    generation into two parts. First, the OAPI document structure is
    traversed, and all the schemas that we generate are gathered up
    into a list of candidates, then we do global conflict resolution
    across the space of all schemas. This allows us to preserve the
    functionality of things affected by schema name - `$ref`, `required`
    properties, and so forth.
    
    This fixes issue #1474 (client response wrapper type colliding with
    a component schema of the same name and improves issue #200 handling
    (same name across schemas, parameters, responses, requestBodies,
    headers).
    
    The new system is gated behind the existing `resolve-type-name-collisions`
    output option. When disabled, behavior is unchanged, oapi-codegen exits
    with an error. This flag is default false, so there is no behavior change
    to oapi-codegen unless it's specified. All current test files regenerate
    without any differences.
    
    Added a comprehensive test which reproduces the scenarios in all the
    PR's and Issues below, and adds a few more, to make sure that references
    to renamed targets are also correct..
    
    Key changes:
    - gather.go: walks entire spec collecting schemas with location metadata
    - resolve_names.go: assigns unique names via context suffix, per-schema
      disambiguation, and numeric fallback strategies
    - Component schemas are privileged and keep bare names on collision
    - Client response wrapper types now participate in collision detection
    - Removed ComponentType/DefinedComp from Schema struct
    - Removed FixDuplicateTypeNames and related functions from utils.go
    
    Obsoletes issues:
    - #1474 Schema name vs client wrapper (CreateChatCompletionResponse)
    - #1713 Schema name vs client wrapper (CreateBlueprintResponse)
    - #1450 Schema name vs client wrapper (DeleteBusinessResponse)
    - #2097 Path response type vs schema definition (Status)
    - #255  Endpoint path vs response type (QueryResponse)
    - #899  Duplicate types from response wrapper vs schema (AccessListResponse)
    - #1357 Schema vs operationId response (ListAssistantsResponse, OpenAI spec)
    - #254  Cross-section: requestBodies vs schemas (Pet)
    - #407  Cross-section: requestBodies vs schemas (myThing)
    - #1881 Cross-section: requestBodies with multiple content types
    
    Obsoletes PRs:
    - #292  Parameter structures params postfix (superseded by context suffix)
    - #1005 Fix generate equals structs (superseded by multi-pass resolution)
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    EOF
    )
    mromaszewicz and claude committed Feb 27, 2026
    Configuration menu
    Copy the full SHA
    914bfd7 View commit details
    Browse the repository at this point in the history
  2. Fix linter issues

    mromaszewicz committed Feb 27, 2026
    Configuration menu
    Copy the full SHA
    1d561ff View commit details
    Browse the repository at this point in the history
  3. fix: apply collision strategies in global phases to prevent oscillation

    When multiple content types map to the same short suffix (e.g.,
    application/json, application/merge-patch+json, and
    application/json-patch+json all mapping to "JSON"), the per-group
    strategy cascade caused an infinite oscillation: context suffix
    appended "RequestBody", then content type suffix appended "JSON",
    then context suffix fired again because the name no longer ended
    in "RequestBody", ad infinitum.
    
    Fix by restructuring resolveCollisions to apply each strategy as
    a global phase: exhaust one strategy across ALL colliding groups
    (re-checking for new collisions after each pass) before advancing
    to the next strategy. This ensures numeric fallback is reached
    when earlier strategies cannot disambiguate.
    
    Also fix resolvedNameForComponent to accept an optional content
    type for exact matching, so each media type variant of a
    requestBody or response gets its own resolved name instead of all
    variants receiving whichever name the map iterator returns first.
    
    Adds Pattern H test case (TMF622 scenario from PR #2213): a
    component that exists in both schemas and requestBodies where the
    requestBody has 3 content types that all collapse to the "JSON"
    short name.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    mromaszewicz and claude committed Feb 27, 2026
    Configuration menu
    Copy the full SHA
    7c90e0b View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    c1245c2 View commit details
    Browse the repository at this point in the history
  5. test: add Pattern I for inline response with x-go-type $ref properties

    Add test case from oapi-codegen-exp#14: an inline response object whose
    properties $ref component schemas with x-go-type: string. In the
    experimental rewrite (libopenapi), this caused duplicate type declarations
    because libopenapi copies extensions from $ref targets. V2 (kin-openapi)
    handles this correctly, but the test guards against future regressions.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    mromaszewicz and claude committed Feb 27, 2026
    Configuration menu
    Copy the full SHA
    b7eb753 View commit details
    Browse the repository at this point in the history
  6. fix: resolve type name mismatches for multi-content-type responses

    When a component response has multiple JSON content types (e.g.,
    application/json, application/json-patch+json, application/merge-patch+json),
    three bugs produced uncompilable code:
    
    1. Duplicate inline type declarations: GenerateGoSchema was called with a
       path of [operationId, responseName] (or [responseName] in the component
       phase), which doesn't include the content type. When multiple content
       types share oneOf schemas with inline elements, they produce
       identically-named AdditionalTypes. If the schemas differ, the result is
       conflicting declarations; if they're the same, duplicate declarations.
       Fix: include a mediaTypeToCamelCase(contentType) segment in the schema
       path when jsonCount > 1, giving each content type's inline types unique
       names. This is guarded by jsonCount > 1 for backward compatibility.
    
    2. Undefined types in unmarshal code: GetResponseTypeDefinitions used
       RefPathToGoType to resolve $ref paths like
       #/components/responses/200Resource_Patch, but without content type
       context. resolvedNameForComponent fell into a non-deterministic prefix
       match, returning an arbitrary per-content-type base name that didn't
       match any defined type when mediaTypeToCamelCase was appended.
       Fix: add resolvedNameForRefPath helper that parses the $ref path and
       delegates to resolvedNameForComponent with the specific content type
       for exact matching.
    
    3. Mismatched types in response struct fields: same root cause as bug 2 —
       the struct field types were derived from the same non-deterministic
       resolution path.
    
    Additionally, promote AdditionalTypes from GenerateTypesForResponses and
    GenerateTypesForRequestBodies to the top-level type list, matching the
    existing pattern in GenerateTypesForSchemas. Without this, inline types
    (e.g., oneOf union members, nested objects with additionalProperties)
    defined inside response/requestBody schemas were silently dropped from
    the output.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    mromaszewicz and claude committed Feb 27, 2026
    Configuration menu
    Copy the full SHA
    20753f4 View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    5e3fede View commit details
    Browse the repository at this point in the history
  8. fix: propagate user name overrides through codegen

    The collision resolver had two bugs when resolve-type-name-collisions
    was enabled:
    
    1. x-go-name was ignored: generateCandidateName() never consulted the
       x-go-name extension, so schemas/responses/requestBodies/parameters/
       headers with explicit Go name overrides would lose them during
       collision resolution.
    
    2. Client wrapper names bypassed the name normalizer:
       generateCandidateName() used UppercaseFirstCharacter(operationID)
       instead of SchemaNameToTypeName(operationID), so configured
       normalizers (e.g. ToCamelCaseWithInitialisms) were not applied to
       client response wrapper type names.
    
    Changes:
    - Add GoNameOverride field to GatheredSchema, populated from x-go-name
      on the parent container (schema, response, requestBody, parameter,
      header) when the component is not a $ref
    - Add extractGoNameOverride() helper to read x-go-name from extensions
    - Add Pinned field to ResolvedName; pinned names are returned as-is
      from generateCandidateName() and skipped by all collision resolution
      strategies (context suffix, content type, status code, param index,
      numeric fallback)
    - Fix client wrapper candidate name to use SchemaNameToTypeName()
    - Add unit tests for GoNameOverride population and pinning behaviour
    - Add integration test patterns K/L/M (x-go-name on schema, response,
      and requestBody) and regenerate
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    mromaszewicz and claude committed Feb 27, 2026
    Configuration menu
    Copy the full SHA
    a46bd1a View commit details
    Browse the repository at this point in the history

Commits on Mar 2, 2026

  1. hack

    jamietanna committed Mar 2, 2026
    Configuration menu
    Copy the full SHA
    0f2f02a View commit details
    Browse the repository at this point in the history
  2. generate

    jamietanna committed Mar 2, 2026
    Configuration menu
    Copy the full SHA
    6632b8a View commit details
    Browse the repository at this point in the history
Loading