'Model output doesn't fit required format' in n8n: fix

Model output doesn't fit required format is the most-viewed structured-output error on the n8n forum: the main thread has 12,435 views, and the user there had Auto-fixing and Retry On Fail on and still got it. Since June 2026 there have been new threads about it with a lead-qualification schema and Gemma in an LLM chain, plus one asking how to get reliable JSON from local models through Ollama. This page explains what the error actually checks, gives the fix for each cause, and covers the related errors Failed to parse agent steps and Could not parse LLM output.

Download the free AI JSON guard template

n8n workflow JSON: clean, validate against your schema, auto-repair, dead-letter log. No credentials inside.

Sheets Bulk AI Runner Pro Kit: $19

Paid option: running a prompt over every row of a Google Sheet? The bulk AI runner accepts JSON output and fills the columns whose headers match its keys. The Pro Kit adds the Google Sheet header CSV, a 10-minute setup guide and an offline test kit (a local OpenAI, Google Sheets and Gmail mock with the 15-scenario runner), so you can watch the retries and resume work before you use a real API key. The AI JSON guard on this page stays free.

How we tested: the causes below were checked against the Structured Output Parser code in n8n 2.44.4. We ran real schemas (including the lead-qualification schema from t/309272) through that parser code with null fields, wrong-case enums, string numbers and unwrapped output, and the free template at the end of this page passed 22 bad-output test cases (code fences, trailing text, invalid JSON, missing fields, wrong types, HTTP 500, double-encoded JSON) on a local n8n 2.44.4 with a mocked OpenAI model. Updated Oct 26, 2026.

What the error means

The message comes from n8n's Structured Output Parser, which is attached when you turn on Require Specific Output Format. In current n8n (checked in the 2.44.4 source), the parser does three things with the model's text. It fails with this message as soon as one of them fails:

  1. If there is a ``` or ```json fence on its own line, it keeps only what's inside. Otherwise it takes the whole text.
  2. It runs a strict JSON.parse. Text before or after the JSON, trailing commas, single quotes, True/None or a cut-off answer all fail here.
  3. It checks the result against your schema wrapped in an output key: the model must return {"output": { …your fields… }}. A missing required field, a wrong type ("2" instead of 2), an enum value in the wrong case ("Hot" vs "hot") or a null in a field typed plain "number" or "string" all fail here. The null case fails even when the field isn't in required.

Three cases give a different message, "The AI model returned an empty response to the Structured Output Parser": a completely empty answer, a bare {}, or JSON with your fields at the top level and no output key. Empty answers usually mean the model ran out of output tokens. A missing output key means the model ignored the format instructions.

Fix it by cause

What the model returnedFix
Your schema pasted into the JSON Example boxSet Schema Type to Define using JSON Schema. With Generate From JSON Example, n8n treats your schema itself as the sample object, so it expects keys like "type" and "properties", and the model's real answer never matches (the cause flagged in t/309272).
null for a field it couldn't fill (no budget mentioned, no name given)Allow it: "budget_numeric": {"type": ["number", "null"]}. Don't force a fake 0, and put only the fields you truly need in required.
Fields at the top level, not inside output (reported as the "empty response" error)The parser adds the wrapper itself, so don't put output in your schema. If the model (often an agent with its own system prompt) still drops it, turn the parser off and parse in a Code node (below). That was the workaround in t/106424.
"Hot", "2", "yes" for an enum, number or boolean fieldList the exact allowed values in the prompt, add a required array, and allow null where a value can be unknown ("type": ["number", "null"]). Or coerce values in code before validating.
"Sure! Here is the JSON…" or an inline ```json {…}```Tell the model to reply with JSON only, or parse in code: take the text from the first { to the last }.
JSON that stops halfwayRaise Maximum Number of Tokens on the chat model, or shorten the schema.
<think>…</think> before the JSON (reasoning models)The parser doesn't strip it. Remove it in code, or use a non-reasoning model for the extraction step.

The fix that holds: parse and validate it yourself

The parser gives you one strict pass and an error that kills the item. A sturdier pattern is to set Require Specific Output Format to off and describe the JSON you want in the prompt. Set the AI node's Settings > On Error to Continue, then add two Code nodes:

// Code node, mode: Run Once for Each Item. Put it right after the AI node.
let raw = $json.text ?? $json.output ?? '';
let t = typeof raw === 'string' ? raw : JSON.stringify(raw);
t = t.replace(/<think>[\s\S]*?<\/think>/gi, '');
const fa = t.lastIndexOf('Final Answer:');
if (fa >= 0) t = t.slice(fa + 'Final Answer:'.length);
const fence = t.match(/```(?:json)?\s*([\s\S]*?)```/i);
if (fence) t = fence[1];
const start = t.search(/[{[]/);
const end = Math.max(t.lastIndexOf('}'), t.lastIndexOf(']'));
let data = null, error = null;
try {
  if (start < 0 || end < start) throw new Error('No JSON found in the model output');
  data = JSON.parse(t.slice(start, end + 1).replace(/,\s*([}\]])/g, '$1'));
  if (data && typeof data === 'object' && 'output' in data && Object.keys(data).length === 1) data = data.output;
} catch (err) { error = err.message; }
return { json: { ok: !error, data, error, raw } };

That handles fences, extra text, <think> blocks, agent "Final Answer:" text, trailing commas and the output wrapper. Then check the fields you actually depend on, and fix the harmless differences:

// Code node, mode: Run Once for Each Item (after the parse step)
const d = $json.data ?? {};
const errors = [];
for (const k of ['category', 'priority', 'summary']) {
  if (d[k] === undefined || d[k] === null || d[k] === '') errors.push(`missing required field ${k}`);
}
if (typeof d.category === 'string') d.category = d.category.trim().toLowerCase();
if (!['billing', 'bug', 'feature', 'other'].includes(d.category)) errors.push('category must be one of billing, bug, feature, other');
if (typeof d.priority === 'string' && /^\d+$/.test(d.priority.trim())) d.priority = Number(d.priority);
if (!Number.isInteger(d.priority) || d.priority < 1 || d.priority > 5) errors.push('priority must be an integer 1-5');
return { json: { ...$json, data: d, ok: $json.ok && errors.length === 0, errors } };

Route on ok with an IF node. For the false branch, send one repair request to the model: the original task, the previous answer and the errors list, with "Return only the corrected JSON." Then parse and validate again. If it still fails, log the item with its raw output instead of guessing. One targeted repair works much better than a blind retry, because the model sees exactly what was wrong. This is also why Auto-fixing Output Parser isn't a safety net: if its single retry fails, the error comes back.

Free template that does all of this: n8n-ai-json-guard.json (import with Workflows → Import from file, no credentials inside). Give it your JSON Schema. It cleans the model's text, validates it, lists every safe fix ("Billing"→"billing", "2"→2), sends the exact validation errors back for up to N repairs, and logs failures to a Data Table with the raw output. You can call it from any workflow with Execute Workflow. Tested on n8n 2.44.4 with 22 bad-output cases.

Parser attached to an AI Agent with tools

If the parser hangs off an AI Agent that also calls tools, the agent's tool loop and the forced output shape pull against each other. n8n's own docs say it directly: "Structured output parsing is often not reliable when working with agents" and "n8n recommends using a separate LLM-chain to receive the data from the agent and parse it" (Structured Output Parser common issues). So turn off Require Specific Output Format on the agent and let it answer in plain text. Then add a Basic LLM Chain after it with the same schema in the parser, or skip the parser and use the clean and validate Code nodes above. The docs also note the parser is meant for the agent's final output, not intermediate steps, and that expressions inside a sub-node like the parser resolve to the first item only.

"Failed to parse agent steps" with Basic LLM Chain

If a Basic LLM Chain with an output parser fails with Failed to parse agent steps, that was a bug, not your prompt: n8n-io/n8n #29903, fixed by PR #33338. Per the GitHub release notes it shipped in n8n 2.30.0 (released Jul 7, 2026). The thread with the root cause is t/298911. Update to 2.30.0 or later. If you can't update yet, turn off Require Specific Output Format and parse with the Code nodes above. Then the chain never goes through the code path that throws.

"Could not parse LLM output"

This one comes from LangChain's ReAct-style agent parser. The model's answer didn't follow the Thought: / Action: / Final Answer: format the agent expects. It usually happens with small or local models. Use the Tools Agent (the default AI Agent in current n8n) with a model that supports tool calling. Or, if you only need structured data, use a Basic LLM Chain without a parser and the Code nodes above. The parse step already keeps only the text after the last Final Answer:.

Local models (Ollama)

On the Ollama model node, set Options > Output Format to JSON. This constrains the output to valid JSON syntax, but not to your fields or values, so keep the validation step. Smaller models are the ones that most often return "Hot", "$2,000" or a missing field.

Download the free AI JSON guard template

n8n workflow JSON: clean, validate against your schema, auto-repair, dead-letter log. No credentials inside.

FAQ

Why does the parser fail more often on an AI Agent with tools?
n8n's docs say structured output parsing is often not reliable with agents. Turn off Require Specific Output Format on the agent, let it answer in plain text, then parse in a separate Basic LLM Chain or validate the JSON in a Code node.

What does "Model output doesn't fit required format" mean in n8n?
The Structured Output Parser could not turn the model's text into JSON that matches your schema wrapped in an output key. Causes: extra text or an inline code fence, invalid or cut-off JSON, a missing required field, a wrong type, an enum value in the wrong case, or null in a field that isn't typed to allow null.

Does Auto-fixing Output Parser fix it?
Sometimes. It sends the error back to the model once. If that retry also fails, the same error is thrown. Validating in a Code node and sending the exact validation errors back, with a dead-letter log, is more reliable.

How do I fix "Failed to parse agent steps" in a Basic LLM Chain?
Update n8n to 2.30.0 or later. The bug (GitHub issue #29903) was fixed by PR #33338. As a workaround, turn off Require Specific Output Format and parse the JSON in a Code node.

Should I use Generate From JSON Example or Define using JSON Schema?
If you are pasting a JSON Schema (with type, properties, enum), choose Define using JSON Schema. Generate From JSON Example treats whatever you paste as a sample object.