Skip to content Documentation index for agents (llms.txt)
Glotto Beta
Get started

Reserved model name diagnostics

One family of SDK-generation diagnostics, on its own page because the table below carries every name thirteen engines declare. Everything on SDK generation diagnostics applies here too: generation stops before writing the target it cannot build, drops that one target, and still writes every other one. A collision between two of your own schemas is a different question with a different remedy, and stays on that page.

Reserved model names

The *_RESERVED_MODEL_NAME codes below are one problem in thirteen languages: a schema whose type name collides with a type the generated SDK itself uses. Left alone, your model silently takes over the SDK’s own references and the build fails with errors pointing at the SDK rather than at the collision — or, in Elixir, does not fail at all and quietly replaces your model.

Generation resolves this for you. The affected SDK emits the model under a deterministic alternative — Data becomes DataModel, and a second collision becomes DataModel2 — and generation reports every rename it applied. Only that language’s type name changes; your other SDKs keep the original name. To choose the name yourself, pin it per target with models: { Data: { name: { swift: MyName } } }, which always wins over the automatic rename and leaves your other SDKs alone; a rename_schema transform renames it in every target instead.

You will only see one of these diagnostics if the rename cannot be applied — it names every colliding schema and the identifier each one shadows. In practice that means one thing: you pinned the name yourself, with models: { Data: { name: { swift: … } } }, onto an identifier that language reserves. A pin is treated as a decision rather than a suggestion, so generation will not quietly substitute a different name for the one you asked for — it refuses that target and tells you. Choose another name, or remove the pin and let the automatic rename resolve it.

Two things hold for all thirteen. Names that merely look built-in are not affected: each engine reserves only what its generated code actually names without qualification, which is why every safe column below has entries in it. And the fixed half of each reserved set — the language builtins and the SDK’s own scaffolding — already covers every type that SDK can use, not only the ones your current endpoints reach, so turning on streaming, pagination or a new auth scheme cannot widen that half under a build that used to work. The derived half is where it can, and that is the next paragraph’s whole subject.

One case cuts across every language, and it is a fact about your spec rather than about the engine. Alongside the fixed vocabulary above, every SDK also declares names derived from your own IR keys — the shared baseline is one class or module per resource: an orders resource makes the Swift SDK declare public final class OrdersResource, and a nested pets/photos pair makes PetsPhotosResource. Because a derived name is a function of your own resource, operation and model keys rather than of the language, it can appear on a spec that used to build — unlike the fixed vocabulary, which a spec either always or never reaches. Adding a resource, turning on SSE for an operation you already had, or growing a discriminated union is what creates the collision, not anything Glotto changed between generations. The remedy is the same either way: rename the model, or rename the resource, operation, event or discriminator value that produced the name it collided with — and the diagnostic always names which one.

Most engines add one or more families beyond that shared resource case, and they differ enough to be worth reading rather than assumed. Throughout — and in the table below — <Resource> is the PascalCase join of a resource key path (a nested pets/photos gives PetsPhotos), <Method> a method key, <Union> a discriminated-union model key, <Member> one of that union’s discriminator values, <Event> a key of an operation’s event_types map, <Scope> a declared OAuth2 scope, and <Parameter> an optional query parameter.

  • Swift and Rust add one <Method>StreamEvent enum per streaming operation with event types — so turning on SSE for an operation you already had is enough to create a collision that a previous generate certified absent.
  • Dart and C# add that same enum and one type per mapped event name, so a new key in an operation’s event_types reserves a name of its own: a sealed class plus its variants in Dart, an abstract record plus its per-event variants in C#.
  • TypeScript and React Native derive the same five families — <Resource>Resource, a <Resource>ResourceWithRawResponse sibling wherever that resource has buffered operations, <Method>StreamEvent, one <Union><Member> per discriminated-union member, and the <Union>Unknown catch-all. They also share a behavior worth knowing about even when the build stays green: TypeScript merges a same-named interface declaration into an existing one rather than rejecting it, so the compiler can accept the collision while your model’s type silently means the SDK’s instead.
  • PHP and Ruby add one <Resource><Method>Request class per operation whose request body is an inline JSON or multipart object.
  • Kotlin adds that same request-body family plus the stream-event pair (<Resource><Method>StreamEvent and one <Resource><Method>StreamEvent<Event> per mapped event) — and is worth knowing about even on a green build for a different reason: the Kotlin SDK emits one file per top-level type, so two declarations claiming one path means one of them never reaches disk, with no compiler error at all.
  • Java collects all four of Kotlin’s families and the discriminated-union pair, because it puts every type in one package. Two of its failure modes are silent, and they are not the same: a collision with a class nested in the generated client compiles clean, because javac binds the SDK’s own reference to its own type and your schema is simply never used; and, separately, where two files would claim one path, one is dropped before the compiler runs — which is Kotlin’s case.
  • Python’s resource family is the largest of the thirteen: four names per node, where TypeScript’s and React Native’s are two and everyone else’s is one. It emits a sync and an async accessor class, plus a WithRawResponse sibling for each where the node has at least one buffered method, so a single orders resource can reserve all four spellings at once. It adds a <Union>Unknown catch-all and no stream-event family at all — its SSE events are emitted as the model types your spec already carries, so there is no per-method union type to collide with.
  • Elixir has the resource case with no suffix (an orders resource emits defmodule Glotto.Orders, so the reserved identifier is a bare <Resource>) plus the discriminated-union pair; see below for the failure it shares with Ruby, and the one thing only it has.
  • Go derives the widest set of the thirteen: the resource accessors, a stream-event trio, a discriminated-union trio, a per-operation option type with one constructor per optional query parameter, and one member per declared OAuth2 scope — all of them sharing the one package-level namespace with the fixed half, because a Go package has no module boundary to keep them apart. Its fixed half, by contrast, holds nothing from the language at all: Go’s builtins and stdlib types are reached under a package qualifier or spelled in lower case, so a PascalCase schema name can never shadow one.

Every row below follows one convention. Collides with lists the fixed vocabulary first (language and runtime builtins the emitted code references or declares, unaffected by your spec), then the SDK’s own declared types (abbreviated to the handful worth recognizing, since several engines’ full lists run past thirty), then every derived family that engine has, phrased as one <X> per <key> in your spec. The abbreviation applies to the first two lists and never to the third — and that is a checked property rather than an editorial promise: our own CI derives the third list by running each engine’s derivation, and runs every identifier in the last two columns through the same resolver glotto generate calls, so a row that understated what its engine reserves fails our build rather than reaching you.

Two diagnostics in this family are not about our names at all. GLOTTO_REACT_NATIVE_COLLIDING_MODEL_NAMES and GLOTTO_TYPESCRIPT_COLLIDING_MODEL_NAMES cover the case where two of your own schemas emit the same type name — foo_bar and fooBar both become FooBar — which would declare that type twice in one module. TypeScript merges two declarations of one name rather than rejecting them, so the usual outcome is a green build shipping a public type that is your two schemas folded together; only a mismatched pair (an interface beside a type alias) is a Duplicate identifier error.

You will normally never see either code, because this is resolved the same way every other collision is: one of the schemas keeps the name and the rest are renamed with the Model suffix and a numeric tail — FooBar, FooBarModel, FooBarModel2 — and every rename is announced when you generate. The schema that keeps the name is the first of the group in sorted order, which depends only on your own keys, so it does not change when you add or rename an unrelated schema.

The code is emitted in one case: you pinned models.<M>.name.<target> on the schema that would have been renamed. Renaming over an explicit pin would give you a type name you did not ask for, so Glotto refuses that target instead — every other target you configured still generates — and the message names the sibling that keeps the name. Pin the other schema instead, drop the pin and let the automatic rename run, or rename one of them everywhere with rename_schema.

Code Language Collides with Safe despite appearances
GLOTTO_SWIFT_RESERVED_MODEL_NAME Swift String, Int, Data, Codable, Sendable, Locale, UUID, Task, and XCTUnwrap (used by generated tests); the SDK’s own Client, APIError, RequestOptions, RawResult; BinaryResponse, DownloadResult, BinaryByteSource, TransportBinaryByteSource and URLSessionBinaryByteSource when binary downloads are declared; SDKs with binary downloads or WebSockets also reserve StreamingTransport, StreamingTransportConfigurationError, StreamingHTTPBody, StreamingHTTPResponse, StreamingWebSocket, StreamingWebSocketMessage, StreamingWebSocketResponse, NIOStreamingTransport, GlottoNIOAbort, GlottoNIOConnection, GlottoNIOHTTPHandler, GlottoNIOInflater, GlottoNIOOpening, GlottoNIOSocketAbortHandler, GlottoNIOUpgradeValidator, GlottoNIOWebSocketHandler, InboundIn and OutboundIn across platforms; and one <Resource>Resource per resource plus one <Method>StreamEvent per streaming operation in your spec Result, Error, Item, Pet
GLOTTO_TYPESCRIPT_RESERVED_MODEL_NAME TypeScript Response, Headers, Promise, Record, Blob, WebSocket; the SDK’s own Client, ApiError, TelemetryContext, RetryBudget, Tokenizer; and one <Resource>Resource per resource, a <Resource>ResourceWithRawResponse per resource with buffered operations, one <Method>StreamEvent per streaming operation, one <Union><Member> per discriminated-union member, and one <Union>Unknown catch-all per eligible union in your spec; BinaryResponse when your spec declares binary responses; the standard SDK error classes BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, MethodNotAllowedError, ConflictError, GoneError, UnsupportedMediaTypeError, UnprocessableEntityError, TooManyRequestsError, InternalServerError, NotImplementedError, BadGatewayError, ServiceUnavailableError, GatewayTimeoutError when an HTTP client runtime is emitted, plus Status<NNN>Error for each explicitly declared numeric 400–599 status without a standard name Error, Date, JSON, Math, Symbol
GLOTTO_RUST_RESERVED_MODEL_NAME Rust Result, Option, String, Vec, Box; the SDK’s own Client, ApiError, RequestOptions, RawResult, TelemetryContext, HttpClient; BinaryResponse and DownloadResult when binary downloads are declared; and one <Resource>Resource per resource plus one <Method>StreamEvent per streaming operation in your spec Error, Clone, Debug
GLOTTO_DART_RESERVED_MODEL_NAME Dart Future, Object, List, Duration, Uri, Stream, StreamController, Completer, Iterable; the SDK’s own Client, ApiError, RawResult, TelemetryContext, TokenStore; BinaryDownload, DownloadResult, JsonResult and FutureOr when binary responses are declared; and one <Resource>Resource per resource, one <Method>StreamEvent per streaming operation, and one <Method>StreamEvent<Event> per mapped event name in your spec Error
GLOTTO_KOTLIN_RESERVED_MODEL_NAME Kotlin List, Map, Set, Any, Unit; the SDK’s own Client, Response, ApiError, RawResult, TokenStore, OAuthTokenResponse, TelemetryContext; BinaryExchange, BinaryResponse and DownloadResult when binary responses are declared; and one <Resource>Resource per resource, one <Resource><Method>Request per inline-object request body, one <Resource><Method>StreamEvent per SSE operation, one <Resource><Method>StreamEvent<Event> per mapped event name, one <Union><Member> per discriminated-union member, and one <Union>Unknown catch-all per eligible union in your spec; the standard SDK error classes BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, MethodNotAllowedError, ConflictError, GoneError, UnsupportedMediaTypeError, UnprocessableEntityError, TooManyRequestsError, InternalServerError, NotImplementedError, BadGatewayError, ServiceUnavailableError, GatewayTimeoutError, plus Status<NNN>Error for each explicitly declared numeric 400–599 status without a standard name Result, Error, Slot, READ, Sequence
GLOTTO_CSHARP_RESERVED_MODEL_NAME C# Task, Stream, Exception, Guid, Encoding; the SDK’s own Client, ApiError, RequestOptions, Response, TelemetryContext; and one <Resource>Resource per resource, one <Method>StreamEvent per streaming operation, one <Method>StreamEvent<Event> per mapped event name, and one <Union><Member> per discriminated-union member and one <Union>Unknown catch-all per eligible union, in your spec; when your spec declares binary responses, BinaryResponse, DownloadResult and the emitted test helper BinaryTransferPeer; the standard SDK error classes BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, MethodNotAllowedError, ConflictError, GoneError, UnsupportedMediaTypeError, UnprocessableEntityError, TooManyRequestsError, InternalServerError, NotImplementedError, BadGatewayError, ServiceUnavailableError, GatewayTimeoutError, plus Status<NNN>Error for each explicitly declared numeric 400–599 status without a standard name String, Object, Enum
GLOTTO_JAVA_RESERVED_MODEL_NAME Java String, Object, Integer, Thread; the SDK’s own Client, Response, RequestOptions, TokenStore, ApiError and the agent-primitive helpers; BinaryExchange, BinaryPayload, BinaryResponse and DownloadResult when binary responses are declared; AsyncStep and AsyncStream when the SDK supports automatic pagination, SSE or NDJSON streaming; and, from your own spec, one <Resource>Resource per resource, a <Resource><Method>Request per inline request body, a <Resource><Method>StreamEvent per SSE operation and a <Resource><Method>StreamEvent<Event> per mapped event name, one <Union><Member> record per discriminated-union value, and one <Union>Unknown catch-all per eligible union; the standard SDK error classes BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, MethodNotAllowedError, ConflictError, GoneError, UnsupportedMediaTypeError, UnprocessableEntityError, TooManyRequestsError, InternalServerError, NotImplementedError, BadGatewayError, ServiceUnavailableError, GatewayTimeoutError, plus Status<NNN>Error for each explicitly declared numeric 400–599 status without a standard name List, Exception, Builder, Slot, Map, Optional, Record
GLOTTO_GO_RESERVED_MODEL_NAME Go Client, APIError, Result, Option, WithBaseURL; BinaryResponse and DownloadResult when binary downloads are declared; and, in the same package-level namespace, one <Resource>Resource accessor per resource, a <Method>StreamEvent with its <Method>StreamEventValue marker and one <Method>StreamEvent<Event> per mapped event name, a <Union><Member> and <Union>Value and <Union>Unknown per discriminated union, a <Method>Option with one With<Method><Parameter> constructor per optional query parameter, and one OAuth2Scope<Scope> per declared OAuth2 scope; the standard SDK error classes BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, MethodNotAllowedError, ConflictError, GoneError, UnsupportedMediaTypeError, UnprocessableEntityError, TooManyRequestsError, InternalServerError, NotImplementedError, BadGatewayError, ServiceUnavailableError, GatewayTimeoutError when an HTTP client runtime is emitted, plus Status<NNN>Error for each explicitly declared numeric 400–599 status without a standard name Context, Reader, Time, Error, Duration, Writer, Handler
GLOTTO_PYTHON_RESERVED_MODEL_NAME Python Exception, Generic, Iterator, AsyncIterator, TypeVar, TypeAdapter, BaseModel, ConfigDict, Field; the SDK’s own Client, AsyncClient, ApiError, RawResponse, RawResult, TelemetryContext, TokenStore; and, per resource in your spec, all four of <Resource>Resource, Async<Resource>Resource, <Resource>ResourceWithRawResponse and Async<Resource>ResourceWithRawResponse (the last two only where the resource has a buffered method), plus one <Union>Unknown catch-all per eligible discriminated union; BinaryResponse and AsyncBinaryResponse when your spec declares binary responses; the standard SDK error classes BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, MethodNotAllowedError, ConflictError, GoneError, UnsupportedMediaTypeError, UnprocessableEntityError, TooManyRequestsError, InternalServerError, NotImplementedApiError, BadGatewayError, ServiceUnavailableError, GatewayTimeoutError, plus Status<NNN>Error for each explicitly declared numeric 400–599 status without a standard name Any, Enum, Callable, Protocol, Data, Result, Response, List, Dict, Optional
GLOTTO_RUBY_RESERVED_MODEL_NAME Ruby Data, Hash, Array, String, Integer, Time, JSON, URI; the SDK’s own Client, Response, ApiError, RawResult, TelemetryContext, OAuth2Scopes and its typed-error, OAuth and agent-primitive classes; BinaryDownload when binary responses are declared; and one <Resource>Resource per resource, one <Resource><Method>Request per inline-object request body, and one <Union><Member> per discriminated-union member and one <Union>Unknown catch-all per eligible union, in your spec; the standard SDK error classes BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, MethodNotAllowedError, ConflictError, GoneError, UnsupportedMediaTypeError, UnprocessableEntityError, TooManyRequestsError, InternalServerError, NotImplementedError, BadGatewayError, ServiceUnavailableError, GatewayTimeoutError, plus Status<NNN>Error for each explicitly declared numeric 400–599 status without a standard name Struct, Symbol, Regexp, READ, WRITE
GLOTTO_PHP_RESERVED_MODEL_NAME PHP String, Int, Array, Object, Float, Bool, Mixed (matched case-insensitively); the SDK’s own Client, ApiError, RequestOptions, RawResult, Response, TokenStore; and one <Resource>Resource per resource, one <Resource><Method>Request per inline-object request body, and one <Union><Member> per discriminated-union member and one <Union>Unknown catch-all per eligible union, in your spec; and BinaryDownload only when an operation declares a binary response; the standard SDK error classes BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, MethodNotAllowedError, ConflictError, GoneError, UnsupportedMediaTypeError, UnprocessableEntityError, TooManyRequestsError, InternalServerError, NotImplementedError, BadGatewayError, ServiceUnavailableError, GatewayTimeoutError, plus Status<NNN>Error for each explicitly declared numeric 400–599 status without a standard name Exception, Closure, Generator, Error
GLOTTO_REACT_NATIVE_RESERVED_MODEL_NAME React Native Response, Headers, Promise, Record, URLSearchParams, WebSocket; the SDK’s own Client, ApiError, TelemetryContext, RawResponse, Uploadable, SecureTokenStore; and, from your own spec, one <Resource>Resource per resource, a <Resource>ResourceWithRawResponse per resource with buffered operations, one <Union><Member> per discriminated-union member, one <Union>Unknown catch-all per eligible union, and a <Method>StreamEvent per streaming operation with event types; BinaryResponse when your spec declares binary responses; the standard SDK error classes BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, MethodNotAllowedError, ConflictError, GoneError, UnsupportedMediaTypeError, UnprocessableEntityError, TooManyRequestsError, InternalServerError, NotImplementedError, BadGatewayError, ServiceUnavailableError, GatewayTimeoutError when an HTTP client runtime is emitted, plus Status<NNN>Error for each explicitly declared numeric 400–599 status without a standard name Map, Error, Date, Set, Symbol, JSON
GLOTTO_ELIXIR_RESERVED_MODEL_NAME Elixir The SDK’s own Client, ApiError, RawResponse, RawResult, TokenStore, Webhook, SdkTest, the agent-primitive helpers (Tokens, Tokenizer, VectorMath, RetryBudget, …) and the optional OAuth / GraphQLClient / EventClient / WebSocketConnection modules; plus, from your own spec, a bare <Resource> per resource (no suffix, unlike every other engine), one <Union><Member> per discriminated-union variant, and one <Union>Unknown catch-all per eligible union, and BinaryDownload when binary responses are declared Map, String, Enum, Jason, Req, Kernel, Keyword — every Elixir and dependency module is namespaced away from yours
GLOTTO_REACT_NATIVE_COLLIDING_MODEL_NAMES React Native Another schema of your own — two models keys that case onto one type name (foo_bar and fooBar both emit FooBar, as do FooBar and foo_bar). Renamed automatically; the code is emitted only when you pinned models.<M>.name.react_native on the schema that would move Two keys that stay distinct after casing, however similar they look
GLOTTO_TYPESCRIPT_COLLIDING_MODEL_NAMES TypeScript The same, for the TypeScript target — both engines resolve a schema’s type name through the same rule, so the same pair collides in both Two keys that stay distinct after casing, however similar they look

Java and Kotlin reserve binary helper names only when an operation declares a binary response. Both then reserve BinaryResponse, DownloadResult and BinaryExchange; Java also reserves BinaryPayload. With no binary responses, a customer model named BinaryResponse keeps that name. Runtime references are qualified so customer models named Java Runnable or Kotlin Set, Flow and Job remain available.

Swift is the strictest case and the reason the behavior exists: it resolves a bare type name to the declaration in the same module before any import, and offers no way to disambiguate. Kotlin’s Unit collides only in the Multiplatform packaging variant, and is reserved across all three so a variant switch cannot break your build.

Ruby is the quietest case: it does not refuse a second definition of a name already declared in scope — it rebinds it — so the collision produces no error at any moment a build could report one. It is worth knowing about even though you should never meet it.

A schema named after a class the Ruby SDK declares would replace that class outright while ruby -c passed, require 'glotto' exited 0, and the SDK’s own test suite stayed green. The failure would arrive as a NoMethodError from inside the SDK the first time you called the affected method. That is why these names are renamed rather than reported: there is no earlier moment at which anything could tell you. Two constants that look like they belong on that list are not on it — READ and WRITE live inside Glotto::OAuth2Scopes, which Ruby treats as a different constant from Glotto::READ, so a schema of either name is left exactly as you wrote it.

Elixir used to be Ruby’s failure one step further, and is now the opposite — it fails loudly. Like Go’s, and unlike every other engine’s, its reserved set contains no language builtin at all: a module named Map in your SDK’s namespace is Glotto.Map, which never captures Elixir’s own Map, so schemas called Map, String or Enum are perfectly safe. What is not safe is a schema named after a module the SDK declares itself.

Which way that fails depends on where the two defmodules land, and the idiomatic package layout moved them apart. Two declarations of one module name in a single file are accepted silently — the later one simply replaces the earlier, and a schema named Client would compile cleanly with your model’s struct, from_map/1 and to_map/1 quietly gone. That was the old single-file SDK. Each module now has its own file, and across two files Elixir refuses outright:

error: cannot define module Glotto.Client because it is currently being defined in lib/glotto/client.ex:1

The build stops; nothing is silently lost. So the rename is no longer protecting you from a missing model — it is protecting you from an SDK that does not compile at all, which is a better failure but still not one you should have to meet. It applies to your resource modules too: this engine names a resource module after the resource key with no suffix, so a pets resource emits defmodule Glotto.Pets and a schema named Pets collides with it. Like the Swift resource case above, that one is a fact about your spec rather than about the engine, so adding the resource later is what creates the collision — the diagnostic names the resource, and renaming or removing it resolves the collision just as renaming the schema does.