Repair Loops for Malformed Output
If the JSON doesn't parse, send the error back to the model and ask it to fix the output.
Repair Loops for Malformed Output is a free AI Agents lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the AI Agents learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Even Strict Modes Fail Sometimes
Older models, edge cases, or non-strict providers occasionally return malformed JSON. Robust agents recover by asking the model to repair its output.
Basic Repair Loop
from pydantic import ValidationError
import json
def call_with_repair(messages, schema, max_attempts=3):
for attempt in range(max_attempts):
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=messages,
response_format={'type': 'json_object'}
)
raw = response.choices[0].message.content
try:
return schema.model_validate_json(raw)
except (json.JSONDecodeError, ValidationError) as e:
messages.append({'role': 'assistant', 'content': raw})
messages.append({
'role': 'user',
'content': f'That output failed to validate: {e}.\nReturn ONLY valid JSON that matches the schema. No prose, no markdown fences.'
})
raise RuntimeError('Could not get valid output after repair attempts.')Why It Works
The model sees the error message and usually corrects on the next turn. Add explicit instructions:
- "No prose"
- "No markdown fences"
- "Match this exact shape: ..."
Strip Markdown Fences
Models often wrap JSON in ```json ... ```. Strip before parsing:
import re
def extract_json(text):
m = re.search(r'```(?:json)?\s*(.*?)```', text, re.S)
if m:
return m.group(1).strip()
return text.strip()
sample = '```json\n{"name": "Alice"}\n```'
print(extract_json(sample))
First-Bracket Slicing
If there is extraneous prose, slice from first { to last matching }:
def find_json_slice(text):
start = text.find('{')
if start == -1:
return None
depth = 0
for i, c in enumerate(text[start:], start):
if c == '{': depth += 1
if c == '}':
depth -= 1
if depth == 0:
return text[start:i+1]
return None
sample = 'Here is your answer: {"name": "Alice", "age": 30} - hope that helps!'
print(find_json_slice(sample))
Tools That Do This For You
- Instructor — wraps Pydantic + repair loops + retries
- Outlines — guaranteed structured output via guided decoding
- jsonformer — token-by-token JSON enforcement (HF models)
Repair Prompts That Work
Include the specific error message and a brief format reminder:
repair_prompt = f'''
Your previous output had this error: {error}
Fix the output. Requirements:
- Valid JSON only
- Match this schema: {json.dumps(schema)}
- No prose, no markdown fences
'''Cost of Repair Loops
Each repair is another LLM call. Cap retries (2-3 is enough — beyond that, the model is unlikely to recover) and log repair rates as a quality metric.
Repair as a Quality Signal
If your repair rate is > 5%, something is wrong: prompt unclear, schema too complex, or model too small. Investigate.
Alternative: Constrained Decoding
Open-source models support grammar-constrained decoding — the model can't produce invalid output at all. Outlines, jsonformer, and llama.cpp grammars do this.
Alternative: Functions Over Schema
Forcing a tool call with strict mode is a cleaner alternative to JSON mode + repair. Use whenever the provider supports it.
Logging Bad Output
Log every repaired output so you can analyze patterns:
log.warning('Repaired output', extra={'raw': raw, 'error': str(e), 'attempt': attempt})When to Give Up
If after N repair attempts the output is still invalid, return an error to the user — don't hallucinate a fallback. Honest failure beats silent corruption.
Repair Loop Pattern
What is the simplest first step in a repair loop?
Recap
Detect parse errors, append them as a tool/user message, ask the model to repair. Limit retries. Prefer strict-mode tool calls to eliminate the need entirely.
Frequently asked questions
Is the “Repair Loops for Malformed Output” lesson free?
Yes — the full text of “Repair Loops for Malformed Output” is free to read here on the web, and the AI Agents course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the AI Agents course, upgrade to CoddyKit PRO.
What will I learn in “Repair Loops for Malformed Output”?
If the JSON doesn't parse, send the error back to the model and ask it to fix the output. You practise AI Agents with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start AI Agents?
No prior experience is required. AI Agents on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Repair Loops for Malformed Output” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this AI Agents lesson?
Yes. Every AI Agents lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- JSON Mode and Tool-Call Outputs
- Pydantic Schema Validation
- Repair Loops for Malformed Output
- Instructor / Outlines for Guaranteed Structure