An inline (anonymous) schema — one written directly under requestBody or a response instead of referenced via $ref — has no name of its own, so your code generator invents one from context: the path, the operation, or a counter. That produces model names like InlineObject1, MessagesPostRequest, or _messages_post_request in your generated SDK — technically valid, but meaningless to a developer reading the client and unstable across regenerations. The fix is to give the schema an explicit name, either by extracting it to components/schemas or setting title. Reproduced 2026-09-21.
What does the generated code actually look like?
Take a spec with two endpoints, each with an inline object in the request body, and no title on either:
openapi: 3.0.3
info:
title: Demo API
version: 1.0.0
paths:
/messages:
post:
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
text:
type: string
responses:
"200":
description: OK
/attachments:
post:
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
url:
type: string
responses:
"200":
description: OK
Running this through OpenAPI Generator v7.25.0 (-g typescript-fetch) logs exactly what it's about to do, in real output:
[main] INFO o.o.codegen.InlineModelResolver - Inline schema created as _messages_post_request. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings _messages_post_request=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings _messages_post_request=NewModel,ModelA=NewModelA in CLI).
[main] INFO o.o.codegen.InlineModelResolver - Inline schema created as _attachments_post_request. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings _attachments_post_request=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings _attachments_post_request=NewModel,ModelA=NewModelA in CLI).
The resulting TypeScript files on disk are MessagesPostRequest.ts and AttachmentsPostRequest.ts. Both operations here happened to have no operationId either, which is a separate problem — see our missing operationId post — but note that the model name is derived independently, from the path and verb, whichever operationId policy you use.
Why do generators invent names like this at all?
Because every generated language needs a concrete type or class for an object, and JSON Schema doesn't require inline schemas to carry identity. OpenAPI Generator's own documentation is direct about it: "Inline schemas are created as separate schemas automatically and the auto-generated schema name may not look good to everyone." Older and default configurations of the tool have shipped names like inline_object_2 or meta_200_response for exactly this reason — a counter or a response-code suffix standing in for a name nobody gave the schema. Type1, Type2, and InlineObject are the same pattern under different generators: whenever a schema has no $ref target and no title, something downstream has to invent a label, and the label carries no information about what the object represents.
This is a JSON Schema and OpenAPI limitation, not a generator bug: nothing in the OpenAPI Object structure requires a schema to be named unless you put it in components/schemas and reference it. An inline schema is, by definition, anonymous.
What's the actual cost?
Three real problems, not just cosmetic ones:
- Unreadable generated code. A developer working against your SDK sees
CreateMessageRequest(fine) or_messages_post_request/InlineObject3(not fine) with zero indication of what fields it holds or why the name looks like that. - Instability across regenerations. Reorder your paths, add a third endpoint before the existing two, and a counter-based name like
InlineObject2can point at a different schema after the next regeneration — a silent breaking change in your SDK's exported types with no change to the API itself. - Duplicate structural schemas staying separate. Because each inline schema is resolved independently, two endpoints with the identical shape (say, both accepting
{ text: string }) generate two separate types instead of sharing one — more surface area for a consumer to reconcile by hand.
How do you fix it?
Two options, and you should reach for the first one whenever the object is reused or represents a real concept in your domain:
Option A — extract to components/schemas and $ref it (preferred):
components:
schemas:
CreateMessageRequest:
type: object
properties:
text:
type: string
paths:
/messages:
post:
operationId: createMessage
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateMessageRequest"
responses:
"200":
description: OK
Every generator names a $ref-ed schema after its key in components/schemas — no ambiguity, no counter, and the same schema referenced from multiple places generates exactly one type.
Option B — set title on the inline schema, when extraction isn't worth it:
paths:
/messages:
post:
operationId: createMessage
requestBody:
required: true
content:
application/json:
schema:
title: CreateMessageRequest
type: object
properties:
text:
type: string
Most generators, OpenAPI Generator included, will use title as the model name instead of deriving one — the same INFO log line quoted above tells you exactly this: "set the title field... to have complete control of the model name."
How to catch this before it ships
- Grep your spec for schemas with no
$refand no siblingtitleinsiderequestBodyand responsecontentblocks — these are the candidates that will get an invented name. - Run generation once against a spec you're not sure about and check the model file list, not just that the build succeeded —
InlineObject,Type1,_something_request, and similar counter-or-context names are the signal. - Run the spec through the free in-browser OpenAPI validator before wiring up generation — it's the fastest way to see your whole schema shape at once, including which objects are inline.
If you're pulling in a spec from a vendor or another team and don't want to hand-audit every inline object, Sourced's hosted docs and SDK pipeline surfaces the actual generated model names in the preview before you publish, so InlineObject2 never reaches a customer's IDE autocomplete. Start free.
FAQ
What's the difference between an inline schema and a $ref schema?
A $ref schema is defined once, usually under components/schemas, and referenced by key wherever it's used — the key becomes the type name. An inline schema is written directly at the point of use, with no name, so a generator has to invent one.
Is InlineObject or Type1 a bug in my spec?
No — it's spec-legal. Anonymous schemas are allowed everywhere JSON Schema is allowed. The generated name is a symptom of not naming the schema, not a validation error.
Does this affect response bodies too, or just request bodies?
Both. Any inline schema anywhere in the spec — request bodies, response bodies, even nested properties — can get an invented name. The examples above use request bodies because they're the most common case, but the fix (extract or title) is identical for responses.
Will setting title fix this for every generator?
Most mainstream generators (OpenAPI Generator, openapi-typescript, Speakeasy, and others) respect title as a naming hint, but behavior isn't standardized across all tools. Extracting to components/schemas and using $ref is the more portable fix because naming-by-reference-key is universal.
Why do two endpoints with an identical inline body still get two different generated types?
Because inline schema resolution happens per-location, not per-shape — the generator doesn't diff schemas for structural equality, it just resolves whatever it finds at each requestBody or response independently. Extracting the shared shape to one named components/schemas entry and referencing it from both places is the only way to get one shared type.
Does this matter for MCP server generation too?
Yes, the same way it matters for SDKs: an MCP tool's input schema is built from the same OpenAPI schema, so an unnamed inline object becomes an unnamed or auto-named parameter block in the tool definition an agent reads — see our guide on generating an MCP server from OpenAPI for how tool schemas are derived.