How to Fix 'JSON parsing error' in LangChain (TypeScript)

By Cyprian AaronsUpdated 2026-04-21
json-parsing-errorlangchaintypescript

What the error means

JSON parsing error in LangChain usually means one thing: the model returned text that is not valid JSON, but your code expected structured output. In TypeScript, this shows up a lot when using StructuredOutputParser, JsonOutputParser, tool calling, or any chain that tries to JSON.parse() model output.

You’ll typically hit it when the LLM adds extra prose, wraps JSON in markdown fences, truncates the response, or returns a slightly malformed object like trailing commas or unquoted keys.

The Most Common Cause

The #1 cause is prompting the model to return JSON, but not enforcing a strict schema or parser. The model then returns something like:

Sure — here’s the result:
```json
{ "name": "Acme", "score": 92 }

That looks fine to a human. It is not valid raw JSON for a parser expecting only the object.

### Broken vs fixed pattern

| Broken | Fixed |
|---|---|
| Ask for JSON in plain English and parse manually | Use `StructuredOutputParser` or `JsonOutputParser` with explicit format instructions |
| Let the model add commentary | Force the model to output only the schema |

```ts
// BROKEN
import { ChatOpenAI } from "@langchain/openai";

const llm = new ChatOpenAI({ temperature: 0 });

const response = await llm.invoke(
  "Return a customer object as JSON with name and score."
);

// This often fails if the model adds text around the JSON
const data = JSON.parse(response.content as string);
// FIXED
import { ChatOpenAI } from "@langchain/openai";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";

const llm = new ChatOpenAI({ temperature: 0 });

const schema = z.object({
  name: z.string(),
  score: z.number(),
});

const jsonSchema = zodToJsonSchema(schema);

const prompt = [
  {
    role: "system",
    content:
      "Return ONLY valid JSON matching this schema. No markdown, no explanation.",
  },
  {
    role: "user",
    content: `Schema:\n${JSON.stringify(jsonSchema)}\n\nInput: Acme scored 92`,
  },
];

const response = await llm.invoke(prompt);
const data = schema.parse(JSON.parse(response.content as string));

If you’re using LangChain parsers directly, prefer them over manual JSON.parse():

import { StructuredOutputParser } from "@langchain/core/output_parsers";
import { z } from "zod";

const parser = StructuredOutputParser.fromZodSchema(
  z.object({
    name: z.string(),
    score: z.number(),
  })
);

const formatInstructions = parser.getFormatInstructions();

Other Possible Causes

1) You are parsing markdown fences as JSON

Models often wrap output in triple backticks. JSON.parse() will fail immediately.

// Broken
const raw = `
\`\`\`json
{"name":"Acme","score":92}
\`\`\`
`;

JSON.parse(raw); // SyntaxError

Fix by stripping fences before parsing, or better, prevent them with stricter instructions.

const cleaned = raw.replace(/```json|```/g, "").trim();
const data = JSON.parse(cleaned);

2) The response was truncated

If maxTokens is too low, you may get half an object and LangChain will throw something like:

  • SyntaxError: Unexpected end of JSON input
  • OutputParserException: Failed to parse
const llm = new ChatOpenAI({
  temperature: 0,
  maxTokens: 50, // too small for structured output
});

Increase token budget and keep outputs small.

const llm = new ChatOpenAI({
  temperature: 0,
  maxTokens: 300,
});

3) The prompt allows extra text

If your system prompt says “explain your reasoning” and also “return JSON,” expect trouble.

// Broken prompt behavior
"You are helpful. Explain your answer and return JSON."

Make it explicit:

// Better
"Return ONLY valid JSON. Do not include explanations, headings, or markdown."

4) Schema mismatch between what you expect and what the model returns

A common LangChain error here is:

  • OutputParserException: Failed to parse
  • Invalid json output

Example:

// You expect a number...
const schema = z.object({
  score: z.number(),
});

// ...but model returns a string.
{"score":"92"}

Fix by aligning schema and prompt. If you need coercion:

import { z } from "zod";

const schema = z.object({
  score: z.coerce.number(),
});

How to Debug It

  1. Log the raw LLM output before parsing

    • Don’t inspect only parsed objects.
    • Print response.content exactly as returned.
  2. Check whether the output contains fences or commentary

    • Look for:
      • “Here’s the result”
      • trailing explanation text after the object
  3. Verify your parser matches your prompt

    • If you use StructuredOutputParser, make sure you pass its format instructions into the prompt.
    • If you use Zod, make sure field types match what the model can realistically produce.
  4. Test with a minimal input

    • Remove tools, memory, retries, and extra chain logic.
    • Call the model once with a single prompt and inspect output.
    • If it works there but fails in your app, the bug is in your chain composition.

Example debug snippet:

const response = await llm.invoke(prompt);

console.log("RAW RESPONSE:");
console.log(response.content);

try {
  const parsed = JSON.parse(response.content as string);
  console.log("PARSED:", parsed);
} catch (e) {
  console.error("JSON parse failed:", e);
}

Prevention

  • Use StructuredOutputParser or Zod-based parsing instead of manual string parsing.
  • Keep prompts strict:
    • “Return ONLY valid JSON”
    • no markdown
    • no commentary
  • Set realistic token limits so structured responses don’t get truncated.
  • Validate raw outputs in logs during development before wiring them into downstream systems.

If you’re building agents for production workflows like claims intake or KYC extraction, treat free-form LLM text as untrusted input. Parse strictly, validate aggressively, and fail closed when the payload is malformed.


Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides