BadRequestError
openai.BadRequestError (HTTP 400)
Stack trace
openai.BadRequestError: Error code: 400 - {'error': {'message': "This model does not support system messages. Please use the 'developer' role instead.", 'type': 'invalid_request_error', 'param': 'messages', 'code': 'invalid_request_error'}} Why it happens
OpenAI's o1 and o3 reasoning models use a fundamentally different architecture optimized for extended chain-of-thought reasoning. These models do not accept traditional system messages because the system context interferes with their internal reasoning process. Instead, they require instructions in a 'developer' role message as the first message in the conversation, which integrates instructions directly into the reasoning chain.
Detection
Check your OpenAI API call logs or console output for 'invalid_request_error' with 'This model does not support system messages'. Add a model check in your code: if model in ['o1', 'o1-mini', 'o3-mini']: validate no system role messages before calling the API.
Causes & fixes
Passing a message with role='system' in the messages array to o1 or o3 models
Remove the system message entirely and convert its content to a 'developer' role message as the first element in messages array
Using legacy code patterns that worked with gpt-4o but not with reasoning models
Refactor your message construction to check the model name; if it's o1/o3, use 'developer' role; otherwise use 'system' role for backward compatibility
Chaining function calls or using framework helpers (LangChain, LiteLLM) that auto-inject system messages
Disable system message injection for reasoning models, or upgrade framework to v2025+ which detects reasoning models and converts system to developer role automatically
Code: broken vs fixed
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
# BROKEN: passing system message to o1 model
response = client.chat.completions.create(
model='o1',
messages=[
{'role': 'system', 'content': 'You are an expert mathematician. Solve problems step by step.'}, # ← This line causes the error
{'role': 'user', 'content': 'What is the square root of 2?'}
],
max_completion_tokens=4000
)
print(response.choices[0].message.content) import os
from openai import OpenAI
client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
# FIXED: use 'developer' role instead of 'system' for o1/o3 models
response = client.chat.completions.create(
model='o1',
messages=[
{'role': 'developer', 'content': 'You are an expert mathematician. Solve problems step by step.'}, # ← Changed 'system' to 'developer'
{'role': 'user', 'content': 'What is the square root of 2?'}
],
max_completion_tokens=4000
)
print(response.choices[0].message.content) Workaround
If you must support both reasoning models and standard models, conditionally build messages: check if the model is in ['o1', 'o1-mini', 'o3-mini', 'o3']; if yes, convert system content to developer role; if no, use system role. This preserves backward compatibility while supporting reasoning models.
Prevention
Adopt a message builder utility that detects the target model and automatically switches between 'system' and 'developer' roles. For production apps, wrap model names in an enum (REASONING_MODELS = ['o1', 'o1-mini', 'o3-mini', 'o3']) and check against it before constructing messages. Document this constraint in your LLM client wrapper so all team members know o-series models use 'developer' role.