OutputParserException
crewai.agents.agent.OutputParserException
Stack trace
Traceback (most recent call last):
File "main.py", line 42, in <module>
result = crew.kickoff(inputs={'topic': 'AI'})
File "/usr/local/lib/python3.11/site-packages/crewai/crew.py", line 189, in kickoff
output = self._execute_tasks(task_list, context)
File "/usr/local/lib/python3.11/site-packages/crewai/crew.py", line 156, in _execute_tasks
task_output = task.execute(agent)
File "/usr/local/lib/python3.11/site-packages/crewai/tasks/task.py", line 127, in execute
return self._parse_output(raw_output)
File "/usr/local/lib/python3.11/site-packages/crewai/tasks/task.py", line 98, in _parse_output
parsed = json.loads(raw_output)
ValueError: Expecting value: line 1 column 1 (char 0)
During handling of the above exception, another exception occurred:
OutputParserException: Could not parse output from agent. Raw output:
```json
Some markdown text before the JSON
{"title": "AI Report", "content": "...
Expected: Valid JSON object matching task output schema. Why it happens
CrewAI tasks expect agents to return responses in a specific structured format (usually JSON matching a Pydantic schema). When the LLM wraps JSON in markdown fences, includes preamble text, returns incomplete JSON, or outputs plain text instead of JSON, the task's output parser fails to deserialize it. This is especially common when using less instruction-tuned models, when the task description doesn't explicitly mandate JSON format, or when the agent's prompt template doesn't enforce strict output formatting.
Detection
Enable debug logging with logging.basicConfig(level=logging.DEBUG) and set callbacks to log raw agent output before parsing. Add a try/except wrapper around crew.kickoff() to inspect the raw task output before it reaches the parser.
Causes & fixes
Agent returned JSON wrapped in markdown fences (```json ... ```)
Add 'Return ONLY raw JSON without markdown fences, code blocks, or any other text.' to the task description. Or use CrewAI>=0.50 which includes auto-stripping of markdown fences in the default output parser.
Agent returned preamble or explanation text before/after the JSON
Modify the task description to: 'Your output MUST be ONLY a JSON object, nothing else. Do not include any text, explanations, or markdown before or after the JSON.' Enforce this in the agent's system prompt.
Task output schema (Pydantic model) fields don't match what the agent was asked to produce
Ensure the task's output_pydantic field names exactly match the field names mentioned in the task description. Use output_file instead of output_pydantic if you only need raw text, not structured data.
Using a non-instruction-tuned base model that ignores format directives
Switch the agent's LLM to an instruction-tuned model. Use gpt-4o-mini, claude-3-5-haiku-20241022, or gemini-2.0-flash. Set model='gpt-4o-mini' in the agent initialization.
Code: broken vs fixed
from crewai import Agent, Task, Crew, Process
from pydantic import BaseModel
import os
class ResearchOutput(BaseModel):
title: str
findings: str
researcher = Agent(
role='Research Analyst',
goal='Analyze topics deeply',
backstory='You are an expert analyst',
model='gpt-4o-mini' # agent doesn't enforce JSON output
)
research_task = Task(
description='Research {topic} and provide findings.', # NO explicit JSON instruction
expected_output='Detailed research findings',
agent=researcher,
output_pydantic=ResearchOutput
)
crew = Crew(
agents=[researcher],
tasks=[research_task],
process=Process.sequential
)
# THIS LINE FAILS — agent returns markdown-wrapped JSON
result = crew.kickoff(inputs={'topic': 'Artificial Intelligence'})
print(result) from crewai import Agent, Task, Crew, Process
from pydantic import BaseModel
import os
from openai import OpenAI
class ResearchOutput(BaseModel):
title: str
findings: str
# FIX 1: Configure LLM client to force JSON output
openai_client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
researcher = Agent(
role='Research Analyst',
goal='Analyze topics deeply',
backstory='You are an expert analyst',
model='gpt-4o-mini', # instruction-tuned model
# FIX 2: Add verbose task description with strict JSON mandate
)
research_task = Task(
# FIX 3: Explicit JSON format instruction in description
description=(
'Research {topic} and provide findings. '
'CRITICAL: Return ONLY a valid JSON object—no markdown, no preamble, no explanation. '
'JSON must have exactly these fields: title (string), findings (string). '
'Example: {"title": "AI Report", "findings": "...details..."}'
),
expected_output='Valid JSON object with title and findings fields',
agent=researcher,
output_pydantic=ResearchOutput # enforces schema validation
)
crew = Crew(
agents=[researcher],
tasks=[research_task],
process=Process.sequential
)
# NOW THIS WORKS — agent output matches schema
try:
result = crew.kickoff(inputs={'topic': 'Artificial Intelligence'})
print(f'Success: {result}')
except Exception as e:
print(f'Parse error (fallback handler): {str(e)}') Workaround
If you can't immediately fix the agent prompt, catch the parse exception, extract JSON from the raw output using regex (r'\{.*\}'), and parse it manually with json.loads(): try: result = crew.kickoff(...) except Exception as e: import re, json; match = re.search(r'\{.*\}', str(e), re.DOTALL); parsed = json.loads(match.group()) if match else None
Prevention
Use CrewAI's built-in tool_use feature or response_format enforcement at the LLM client level to guarantee schema-valid outputs without relying on agent prompt compliance. Implement a TaskCallback to log raw agent output before parsing. Validate task output_pydantic schemas are simple (2-4 fields max) to reduce parsing failure surface area. Test each agent-task pair in isolation before adding to the full crew pipeline.