High severity HTTP 400 intermediate · Fix: 2-5 min

BadRequestError

openai.BadRequestError (HTTP 400)

What this error means
OpenAI's o1 and o3 reasoning models do not support system messages in the messages array; use developer role in the first message instead.

Stack trace

traceback
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'}}
QUICK FIX
Replace role='system' with role='developer' as your first message when using o1, o1-mini, or o3-mini models.

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

1

Passing a message with role='system' in the messages array to o1 or o3 models

✓ Fix

Remove the system message entirely and convert its content to a 'developer' role message as the first element in messages array

2

Using legacy code patterns that worked with gpt-4o but not with reasoning models

✓ Fix

Refactor your message construction to check the model name; if it's o1/o3, use 'developer' role; otherwise use 'system' role for backward compatibility

3

Chaining function calls or using framework helpers (LangChain, LiteLLM) that auto-inject system messages

✓ Fix

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

Broken - triggers the error
python
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)
Fixed - works correctly
python
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)
OpenAI o1 and o3 models require instructions via 'developer' role as the first message instead of 'system' role, because the reasoning process needs to integrate instructions directly into the thought chain.

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.

Python 3.9+ · openai >=1.3.0 · tested on 1.40.0
Verified 2026-04 · o1, o1-mini, o3-mini, o3
Verify ↗

Community Notes

No notes yetBe the first to share a version-specific fix or tip.