Skip to content

fix: keep the full factory name of a go model ending in able - #8110

Merged
Vincent Biret (baywet) merged 1 commit into
microsoft:mainfrom
wiebren:fix/go-able-model-name
Aug 31, 2026
Merged

fix: keep the full factory name of a go model ending in able#8110
Vincent Biret (baywet) merged 1 commit into
microsoft:mainfrom
wiebren:fix/go-able-model-name

Conversation

@wiebren

Copy link
Copy Markdown
Contributor

Description

A go client generated from a document containing a model whose name ends in able does not
compile. The model itself is generated correctly:

// models/provider_unavailable.go
func CreateProviderUnavailableFromDiscriminatorValue(parseNode ...) (...) {

but every error mapping that references it asks for a different symbol, with the trailing
able gone:

errorMapping := i2ae...ErrorMappings {
    "503": i138...CreateProviderUnavailFromDiscriminatorValue,   // <- never defined
}
items/item_stats_request_builder.go:49:76: undefined:
    i138....CreateProviderUnavailFromDiscriminatorValue

One schema name breaks the build of the whole package, so every operation in the client is
unusable, not just the endpoint that maps the error. Any name ending in able triggers it —
ProviderUnavailable, Cancelable, Immutable, Table, Available — and only go is
affected: the same document generates correctly for the other languages.

(This may be the same defect as #2955, closed in 2023 without a recorded root cause — same
symptom, an undefined Create...FromDiscriminatorValue in a go request builder.)

Root cause

The go writer names a model's inserted interface by appending able (Domain
Domainable), and GoConventionService.GetImportedStaticMethodName recovers the factory
name from the rendered type name by trimming that suffix back off. The refiner only rewrites
request executor return types and request bodies to the interfaces
(CopyModelClassesAsInterfaces); an error mapping (and a property factory) still points
at the model class. For those, the rendered name is the model's own name — and when that
name itself ends in able, the trim eats part of it: ProviderUnavailable cannot be told
apart from the interface of a model called ProviderUnavail, and the trim wins.

Changes Made

  • GetImportedStaticMethodName only trims the suffix when the type does not resolve to
    a model class (code is not CodeType { TypeDefinition: CodeClass }). Types that resolve
    to the inserted interface — and unresolved names, preserving today's behavior for them —
    are trimmed exactly as before; a model class keeps its full name.
  • New test WritesRequestExecutorBodyForErrorModelNamedWithAbleSuffix covering both sides:
    a class named ProviderUnavailable keeps its name in the factory reference, and a mapping
    through a model interface (Error5XXable) still trims to CreateError5XX....
  • CHANGELOG entry under Unreleased/Changed.

Testing

  • The full Kiota.Builder.Tests suite passes: 2291 passed, 0 failed.

  • Reproduction, before/after. A minimal document with an error schema named
    ProviderUnavailable referenced from a 503 response, generated with -l go and compiled
    with go 1.25:

    emitted reference go build ./...
    before CreateProviderUnavailFromDiscriminatorValue undefined: ...CreateProviderUnavailFromDiscriminatorValue
    after CreateProviderUnavailableFromDiscriminatorValue builds
  • A production document of ≈100 operations (which is where this was found) generated
    with this branch compiles cleanly with go build ./....


Generated with Claude Code

The go writer names a model's inserted interface by appending able, and
GetImportedStaticMethodName recovered the model name for factory references
by trimming that suffix off the rendered type name. The round trip is lossy
for a model whose own name ends in able: an error mapping for
ProviderUnavailable emitted CreateProviderUnavailFromDiscriminatorValue, a
symbol that is never generated, so the whole package failed to compile.
Error mappings (and property factories) reference the model class directly
rather than the interface, which is why only these call sites were hit.

Trim the suffix only when the type does not resolve to a model class: the
inserted interfaces and unresolved names keep today's behavior, a class
whose own name ends in able keeps its name.

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

@baywet Vincent Biret (baywet) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the contribution!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes a Go codegen defect where model names ending in able caused incorrect Create...FromDiscriminatorValue factory references (due to over-aggressive suffix trimming), leading to generated clients that don’t compile.

Changes:

  • Updates Go GetImportedStaticMethodName to trim the able suffix only when the type does not resolve to a CodeClass, preserving full class names like ProviderUnavailable.
  • Adds a Go writer regression test covering both: (1) a model class whose name ends with able and (2) an inserted model interface type that should still be trimmed.
  • Documents the fix in CHANGELOG.md under Unreleased.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/Kiota.Builder/Writers/Go/GoConventionService.cs Prevents erroneous able trimming when the type resolves to a model class, fixing broken factory symbol references in Go output.
tests/Kiota.Builder.Tests/Writers/Go/CodeMethodWriterTests.cs Adds regression coverage ensuring class-names-with-able keep full factory names while interface types still trim correctly.
CHANGELOG.md Records the Go fix and its impact under Unreleased/Changed.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@baywet
Vincent Biret (baywet) added this pull request to the merge queue Aug 31, 2026
Merged via the queue into microsoft:main with commit 22ae7b2 Aug 31, 2026
313 checks passed
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.

3 participants