DEV Community

AI JSONMedic
AI JSONMedic

Posted on • Originally published at aijsonmedic.com

LangChain JsonOutputParser: Fix Malformed JSON from LLMs

LangChain's JsonOutputParser is one of the most useful tools in the LangChain ecosystem — until your LLM returns malformed JSON and everything crashes.

This article was originally published at AI JSONMedic.


The Problem

LLMs are probabilistic. Even with a structured prompt, models sometimes return:

  • Single-quoted JSON: {'key': 'value'} instead of {"key": "value"}
  • Trailing commas: {"key": "value",}
  • Markdown code fences wrapping the JSON: json\n{...}\n
  • Truncated responses that cut off mid-object

JsonOutputParser raises OutputParserException on all of these.

Basic Setup

from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field

class MovieReview(BaseModel):
    title: "str = Field(description=\"Movie title\")"
    rating: float = Field(description="Rating from 0 to 10")
    summary: str = Field(description="One sentence summary")

parser = JsonOutputParser(pydantic_object=MovieReview)

prompt = PromptTemplate(
    template="Review this movie: {movie}\n{format_instructions}",
    input_variables=["movie"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

model = ChatOpenAI(temperature=0)
chain = prompt | model | parser

result = chain.invoke({"movie": "Inception"})
print(result)
Enter fullscreen mode Exit fullscreen mode

Making It Robust — Auto-Repair Strategy

The most reliable approach is to add a repair step before the parser:

from json_repair import repair_json
from langchain_core.output_parsers import StrOutputParser
import json

def robust_json_parse(text: str) -> dict:
    """Parse JSON from LLM output, with auto-repair for common errors."""
    # Strip markdown code fences if present
    if text.strip().startswith("```

"):
        lines = text.strip().split("\n")
        text = "\n".join(lines[1:-1] if lines[-1] == "

```" else lines[1:])

    # Try direct parse first
    try:
        return json.loads(text)
    except json.JSONDecodeError:
        pass

    # Auto-repair (handles single quotes, trailing commas, etc.)
    repaired = repair_json(text)
    return json.loads(repaired)

# Use with a raw string output parser + manual repair
chain = prompt | model | StrOutputParser() | robust_json_parse
Enter fullscreen mode Exit fullscreen mode

Using OutputFixingParser

LangChain also has a built-in OutputFixingParser that uses a second LLM call to fix bad output:

from langchain.output_parsers import OutputFixingParser

fix_parser = OutputFixingParser.from_llm(
    parser=JsonOutputParser(pydantic_object=MovieReview),
    llm=ChatOpenAI(temperature=0)
)

chain = prompt | model | fix_parser
Enter fullscreen mode Exit fullscreen mode

This works but uses an extra API call per failure. Use it when accuracy is critical and cost is acceptable.

Using RetryOutputParser

For structured retry logic:

from langchain.output_parsers import RetryOutputParser

retry_parser = RetryOutputParser.from_llm(
    parser=JsonOutputParser(pydantic_object=MovieReview),
    llm=model,
    max_retries=3
)
Enter fullscreen mode Exit fullscreen mode

Summary

Strategy When to use
json-repair library Fast, no extra API calls, handles most cases
OutputFixingParser Critical accuracy, cost not a concern
RetryOutputParser When the original prompt just needs re-running
Manual strip + parse Code fences only, no other errors

For quick one-off JSON repair from LLM output, AI JSONMedic handles single quotes, trailing commas, Python booleans, and truncated JSON in the browser.

Top comments (0)