FlowKit

n8n Structured Output Parser: getting reliable JSON out of an AI Agent

Published 21 July 2026 · 6 min read

An n8n AI Agent that's supposed to return {"category": "urgent", "score": 8} sometimes answers Here is the requested classification: {"category": "urgent", "score": 8}, or wraps the JSON in a Markdown code block with triple backticks. The Set or Switch node right after it then blows up with a parsing error — not because the model got the substance wrong, but because it dressed up the right answer with a pleasantry. The Structured Output Parser exists for exactly this problem: it forces an LLM's output format and rejects anything that doesn't match the expected schema.

How it works

The Structured Output Parser is a sub-node that plugs into the ai_outputParser connection of an AI Agent or a Basic LLM Chain. It does two things at once:

  1. It automatically enriches the prompt sent to the model with precise formatting instructions ("respond only with a JSON object matching this schema…") — you don't have to write any of that in the system message yourself.
  2. It validates the model's response against the defined schema. If it matches, the parsed JSON replaces the raw text at the node's output. If it doesn't, the node throws an explicit error instead of letting an unusable text blob flow downstream.

To use it, you first need to enable "Require Specific Output Format" in the settings of the root node (AI Agent or Basic LLM Chain). That toggle is what makes the ai_outputParser connection point appear on the node — without it, there's nothing to plug a parser into.

Step 1 — Define the schema

The node offers two ways to specify the expected structure:

  • Generate From JSON Example: paste a representative example, and n8n infers the schema from it. The fastest way to get started:
{
  "category": "urgent",
  "priority_score": 8,
  "summary": "Unhappy customer demanding a refund within 48h"
}
  • JSON Schema: write the schema yourself, useful once you need precise constraints — an enumeration of allowed values, an optional field, a numeric min/max:
{
  "type": "object",
  "properties": {
    "category": {
      "type": "string",
      "enum": ["urgent", "customer", "administrative", "newsletter"]
    },
    "priority_score": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10
    },
    "summary": { "type": "string" }
  },
  "required": ["category", "priority_score", "summary"]
}

The enum mode is particularly useful ahead of a Switch node: it eliminates by construction the spelling variants ("Urgent" vs "urgent" vs "URGENT") that break an exact branch match.

Need an array of objects rather than a single object — say, a list of tickets extracted from one email? The neighboring Item List Parser node covers that exact case, with the same schema principle.

Which parser for which situation

Situation Node to use Why
Single object, quick start Structured Output Parser (Generate From JSON Example) Schema inferred from one pasted example
Enums, min/max, optional fields Structured Output Parser (JSON Schema mode) Precise constraints, safe before a Switch
List of objects from one input Item List Parser Built for arrays, same schema principle
Model occasionally breaks the format Auto-fixing Output Parser wrapping the schema A second LLM pass repairs formatting slips
Agent with tools attached Basic LLM Chain re-reading the agent's answer Avoids "Failed to parse agent steps"

Step 2 — The trap of tool-using agents

This is the point n8n's own documentation flags explicitly, and it trips up a good share of workflows: wiring a Structured Output Parser directly to an AI Agent equipped with tools (search, an API call, a database read) is unreliable in practice. The agent alternates between reasoning steps and tool calls before its final answer; that intermediary format doesn't always play well with the parser's strict validation, and surfaces as errors like "Failed to parse agent steps" or a parser that the node simply ignores.

The pattern that holds up reliably in production: let the agent answer freely, in natural text, using its tools. Then have a second, dedicated node — a Basic LLM Chain equipped with the Structured Output Parser — re-read that final answer and reformat it into compliant JSON. Two nodes, two responsibilities: the agent reasons and acts, the formatting chain structures. It's more verbose than a single node, but noticeably more robust — consistent with the pattern detailed in our guide on custom tools for an n8n AI Agent.

Step 3 — Auto-fixing Output Parser: catching formatting slips

Even with a well-written schema, a model sometimes drops a closing brace, or slips in an invalid trailing comma. Rather than failing the workflow at the first slip, the Auto-fixing Output Parser node sits in between: it wraps an existing Structured Output Parser and, on a validation failure, automatically sends the faulty output back to the LLM along with the error message, asking it to fix it — then re-validates.

Worth knowing before you enable it everywhere by default:

  • Each correction consumes one extra LLM call — a cost and a latency hit to budget into the workflow (see our guide on tracking AI call costs).
  • It's a safety net for formatting errors, not content errors: if the model invents a category outside the enum, Auto-fixing can repair the syntax, but it won't fix wrong business logic.

The mistakes that cost you an evening

  • JSON wrapped in a Markdown block: the model answers with a fenced ```json\n{...}\n``` block instead of raw JSON. The Structured Output Parser handles most of these natively, but a system message that explicitly states "respond with raw JSON only, no code block" still cuts down failures further.
  • Quotes or backticks trapped inside a text value: a summary field containing unescaped JSON-special characters breaks parsing. Ask the model to avoid special characters in free-text fields, or validate downstream in a Code node.
  • {{ $json.field }} always returning the same value: inside a sub-node like the Structured Output Parser, an expression only evaluates once, against the first item of the batch — not item by item like a root node. If the schema needs to vary per item, build it upstream in a Code node.
  • Parser wired but ignored: check that "Require Specific Output Format" is checked on the root node — a parser connected without that option enabled is simply not taken into account.

Where this actually matters

Any workflow that feeds an LLM's output into a structured node — Switch, Set, a database write — needs this reliability. The Urgency & priority scoring for emails workflow from the Inbox AI Pack (€79) relies on exactly this mechanism to turn an LLM's reading of an email into a category and priority_score a Switch node can act on, without ever breaking on a malformed answer. The same logic applies on the audit summary report side of the Compliance & Audit Pack (€149), where the structured JSON feeds the final document directly.

Once this guardrail is in place, the rest of the workflow — Switch, Supabase write, Slack notification — can fully trust the shape of what comes in. It's exactly this kind of detail — invisible while it works, and a hard blocker the moment it breaks in production — that separates an AI prototype from a workflow you can leave running unsupervised. If you want to make sure that reliability holds over time, our guide on n8n Evaluations shows how to build a test set that catches a format regression before a customer finds it for you. And if what your LLM reads comes out of contracts or reports, our guide to RAG over PDFs with n8n covers the extraction stage upstream of this parser.

FAQ

Frequently asked questions

Does the Structured Output Parser work with an AI Agent that has tools attached?

Technically yes, but n8n advises against that pairing: an agent that alternates between tool calls and a final answer produces an internal reasoning format the parser struggles to validate reliably, often surfacing as a "Failed to parse agent steps" error. The recommended pattern is to let the agent answer freely, then have a separate Basic LLM Chain re-read that answer, with the Structured Output Parser attached to that chain instead.

Do I have to write the JSON Schema by hand?

No, not necessarily. The node offers a "Generate From JSON Example" mode: paste a representative example object and n8n infers the schema automatically. That covers most cases; the manual JSON Schema mode becomes useful once you need precise constraints — an enum, a minimum value, explicit optional fields.

What does the Auto-fixing Output Parser add over the Structured Output Parser?

The Structured Output Parser validates and rejects: if the model's output doesn't match the schema, the node throws an error and the workflow stops (unless you handle the error explicitly). The Auto-fixing Output Parser wraps that validation in a retry loop: on failure, it sends the faulty output back to the LLM along with the validation error and asks it to fix it, then re-validates. The cost is one extra LLM call per correction.

Why does {{ $json.field }} inside the Structured Output Parser always return the same value across several items?

Because n8n sub-nodes (output parsers included) don't process items one by one the way a root node does: an expression inside a sub-node resolves once, against the first item of the batch. If the schema needs to vary per item, build it upstream in a Code or Set node instead of inside the sub-node's own expression.

Bundle FlowKit Complet

€269