How to Fix 'JSON parsing error' in AutoGen (Python)
A JSON parsing error in AutoGen usually means one of the agent messages, tool outputs, or model responses was expected to be valid JSON but wasn’t. You’ll typically hit it when using structured outputs, function calling, tool results, or when a custom agent returns plain text where AutoGen expects a JSON payload.
In practice, this shows up as a runtime failure inside AssistantAgent, UserProxyAgent, or a tool wrapper when AutoGen tries to deserialize content with json.loads(...).
The Most Common Cause
The #1 cause is returning Python objects or malformed strings where AutoGen expects a JSON string.
This happens a lot with custom tools and reply functions. You return a dict, list, or formatted text directly instead of serializing it properly.
Broken vs fixed
| Broken pattern | Fixed pattern |
|---|---|
| Returns non-JSON text | Returns valid JSON string |
| Uses single quotes | Uses double quotes |
| Includes trailing commas/comments | Strict JSON only |
# BROKEN: custom tool returns Python dict or invalid JSON-like text
from autogen import AssistantAgent, UserProxyAgent
def get_customer_data(customer_id: str):
# This is a Python dict, not a JSON string
return {
"customer_id": customer_id,
"status": "active",
}
assistant = AssistantAgent(
name="assistant",
llm_config={"config_list": [{"model": "gpt-4o-mini", "api_key": "YOUR_KEY"}]},
)
user_proxy = UserProxyAgent(name="user_proxy")
# If AutoGen expects JSON here and gets raw dict / malformed text later,
# you'll see errors like:
# json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes
# FIXED: serialize the tool output explicitly
import json
from autogen import AssistantAgent, UserProxyAgent
def get_customer_data(customer_id: str):
payload = {
"customer_id": customer_id,
"status": "active",
}
return json.dumps(payload) # valid JSON string
assistant = AssistantAgent(
name="assistant",
llm_config={"config_list": [{"model": "gpt-4o-mini", "api_key": "YOUR_KEY"}]},
)
user_proxy = UserProxyAgent(name="user_proxy")
If your code uses function_map, register_function, or a custom reply handler, the same rule applies: return valid JSON if the downstream parser expects JSON.
Other Possible Causes
1) The model returned extra prose around the JSON
AutoGen can parse a response that looks like this:
Here is the result:
{"approved": true, "score": 0.91}
But if your parser expects raw JSON only, that leading sentence breaks it.
# Broken prompt pattern
system_message = """
Return JSON with keys approved and score.
"""
# Better: constrain output harder
system_message = """
Return ONLY valid JSON.
No markdown.
No explanation.
"""
If you’re using response_format or structured extraction logic, make the instruction strict.
2) Single quotes instead of double quotes
Python prints dicts with single quotes. JSON does not allow that.
# Broken output
"{'approved': True, 'score': 0.91}"
# Valid JSON
'{"approved": true, "score": 0.91}'
This comes up when you do:
return str({"approved": True})
Instead:
import json
return json.dumps({"approved": True})
3) Tool output contains non-serializable objects
Datetime objects, Decimal values, and custom classes often blow up serialization before AutoGen even gets to parse them.
from datetime import datetime
from decimal import Decimal
import json
payload = {
"timestamp": datetime.utcnow(), # not JSON serializable by default
"amount": Decimal("12.50"), # not JSON serializable by default
}
# Fix:
payload = {
"timestamp": datetime.utcnow().isoformat(),
"amount": str(Decimal("12.50")),
}
json.dumps(payload)
If you’re seeing errors like:
- •
TypeError: Object of type datetime is not JSON serializable - •
json.decoder.JSONDecodeError: Expecting value
check the tool return value first.
4) Malformed function schema or tool config
If you register tools with bad parameter schemas, AutoGen can fail while building or parsing the function call payload.
# Broken schema example: missing required structure / invalid types
tool_schema = {
"name": "get_policy",
"description": "Fetch policy data",
"parameters": {
"type": "object",
"properties": {
"policy_id": {"type": "string"},
},
# if required fields are wrong/missing for your setup,
# model/tool routing may fail downstream
},
}
Make sure your schema matches what your AutoGen version expects. For function calling setups, validate against the OpenAI-style schema shape used by your agent configuration.
How to Debug It
- •
Print the exact payload before AutoGen parses it
- •Log tool returns and agent replies.
- •Look for single quotes, trailing commas, markdown fences, or extra prose.
- •
Validate with
json.loads()locally- •Take the exact string causing failure and test it in isolation.
- •If this fails outside AutoGen, the problem is your payload shape.
import json
candidate = "{'approved': True}"
json.loads(candidate) # will fail immediately
- •
Inspect whether the failure is from input or output
- •Input side: malformed message passed into an agent/tool.
- •Output side: model response not matching expected schema.
- •In logs, check whether the error happens during send, receive, or tool execution.
- •
Reduce to one agent and one tool
- •Remove nested agents, memory hooks, and extra callbacks.
- •Start with a single
AssistantAgent+ one function. - •Reintroduce complexity only after the base path works.
Prevention
- •Always serialize tool outputs with
json.dumps(...)before returning them if downstream code expects JSON. - •Tell the model exactly what to emit:
- •“Return ONLY valid JSON”
- •“No markdown”
- •“No explanation”
- •Keep schemas strict and test them separately from your agent loop.
- •Add a small validation helper in your tool layer so bad payloads fail early:
import json
def ensure_json(value):
if isinstance(value, str):
json.loads(value)
return value
return json.dumps(value)
If you’re seeing JSON parsing error in AutoGen Python code, start by checking what your tool or agent actually returned. In most cases, the fix is not in AutoGen itself — it’s in making sure every boundary between Python objects and LLM-facing text is explicit and valid JSON.
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
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