After this topic
You will stop asking the model for “JSON only” and hoping. You will have a Zod schema, a generateText call with Output.object, and a typed object you can save to a database — or a loud failure if the model cannot fill the shape.
Likely text is not a contract
If the next line of code needs fields — name, role, a list of tasks — you need a schema, not a prompt that says “return JSON”.
You already know the model writes likely text. If you ask it for JSON in the prompt — “return JSON only” — you still get likely text. Often that is JSON. Often it is JSON wrapped in markdown fences. Often it has a preface (“Sure, here is…”). JSON.parse throws. Your form never fills.
Production features that need data — a profile object, a list of tasks, a routing decision — cannot afford a string you hope is JSON. They need a contract: these keys, these types, or fail loud.
This is the same Day 1 lesson with a new surface. Constraining the guess is your job. A schema is a constraint the SDK can enforce. A sentence in the prompt is a suggestion the model can ignore.
Files
- 01
JSON.parse on a guess
The model often wraps JSON in ```json fences or adds a sentence. That throws. Output.object exists so you do not police that.
generateText + Output.object
In AI SDK v6, structured data is still generateText. You pass an output option, not a separate generateObject call (that API is gone). Output.object takes a Zod schema. You read result.output — parsed, typed, or the call failed.
The schema is the shape. The prompt is the instruction. Keep both small. A 40-field object will be slow, expensive, and more likely to fail validation. Split work across steps if you must.
Providers that support native structured output will use it. Providers that do not still get a validated object — the SDK retries or repairs according to the current docs. You write one call either way.
Files
- 01
Zod is the contract
z.object({…}) is runtime validation and TypeScript types. The model is steered to fill those fields. You do not regex the keys out.
- 02
output, not object
v6 returns { output } from generateText. If the model cannot satisfy the schema, the SDK fails loud — better than a half-valid string in production.
- 03
prompt is still just text
The schema does not replace the prompt. It constrains the completion. Say what you want; the schema says what shape it must have.
When the next line needs fields
Use Output.object when code will read properties: save to Postgres, render a card, pick a branch, call another API. The user never sees the JSON. They see a form that filled itself, or a ticket that was created.
Use plain generateText or streamText when the user is meant to read an essay. Streaming a half-object onto the screen is worse than waiting for a valid one.
Enums and small unions are gold. z.enum(['billing', 'bug', 'other']) as a routing decision is a better product than a free-text “category” you then parse with more AI.
- Data the code will use — Output.object
- Prose the user will read — generateText / streamText
- A choice among known options — z.enum, not a paragraph
Trade-offs
Larger schemas cost more tokens and more latency. Prefer the smallest object that unblocks the next step. If validation keeps failing, the prompt is unclear or the schema is too tight — fix those before retrying forever.
Nested objects and long arrays are where models get sloppy. Flatten. Cap array length in the schema. Two small generateText calls beat one giant blob.
Failures should be loud. Catch them, show the user a retry, log the raw error. Do not JSON.parse a consolation string “just in case.” That is how you ship a profile named ```json.
Related patterns
Docs
Official API reference for this chapter.
Common questions
- What is “Structured outputs with Zod”?
- generateText with Output.object enforces a Zod schema so the model returns JSON you can trust in TypeScript.
- What will I be able to do after this lesson?
- You will stop asking the model for “JSON only” and hoping. You will have a Zod schema, a generateText call with Output.object, and a typed object you can save to a database — or a loud failure if the model cannot fill the shape.
- How long does this lesson take?
- About 18 minutes of reading. It is a free chapter in the AI SDK Patterns TypeScript course.
- When should I not use this?
- Larger schemas cost more tokens and more latency. Prefer the smallest object that unblocks the next step. If validation keeps failing, the prompt is unclear or the schema is too tight — fix those before retrying forever.
Written by Akash Panchal·Updated August 29, 2026