Fixing OpenAI 400: Why JSON Mode Requires the word 'json' in Your Prompt

beginner🧠 AI Tools2026-05-24| Python (OpenAI SDK v1.0+), Node.js, OpenAI API (Models: gpt-4o, gpt-4o-mini, gpt-4-turbo, gpt-3.5-turbo-0125)

Error Message

openai.BadRequestError: Error code: 400 - {'error': {'message': "'messages' must contain the word 'json' in some form, to use 'response_format' of type 'json_object'.", 'type': 'invalid_request_error', 'param': 'messages', 'code': 'invalid_request_error'}}
#openai#json-mode#python#gpt-4o#api-error

The Frustrating 400 Error

You’ve toggled on JSON mode using response_format={"type": "json_object"}, expecting a clean, structured response. Instead, the API kicks back a 400 Bad Request error. It’s a common hurdle that stops many developers in their tracks. The error looks like this:

openai.BadRequestError: Error code: 400 - {'error': {'message': "'messages' must contain the word 'json' in some form..."}}

Why This Happens

Think of JSON mode as a strict guardrail rather than a smart feature. When you enable it, the API forces the model's output to be syntactically correct JSON. However, the model isn't a mind reader. If your prompt asks for a casual conversation but the API settings force a JSON structure, the two will clash.

To prevent this conflict, OpenAI enforces a simple safety check: at least one message in your request must contain the string "json". If you forget this, the API assumes the model might try to output plain text, which would break the JSON constraint, so it rejects the request entirely before spending any tokens.

How to Fix Your Prompt

The fix is straightforward. You need to explicitly tell the model to use JSON somewhere in your message history. While you can put this anywhere, adding it to the system message is the most reliable way to set the right expectations from the start.

Method 1: The System Message (Best Practice)

Define the output format in your system instructions. This ensures the model understands its primary goal is data generation, not chitchat.

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "You are a data extraction bot. Always return the results in JSON format."},
        {"role": "user", "content": "What are the 3 largest cities in Japan by population?"}
    ],
    response_format={"type": "json_object"}
)

Method 2: The User Message

If you aren't using a system message, simply mention the format in your direct request. The API check is case-insensitive; "JSON" or "json" both work perfectly.

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "user", "content": "Give me a list of 5 healthy snacks. Format: JSON."}
    ],
    response_format={"type": "json_object"}
)

Full Python Implementation

Here is a script that handles the prompt requirement and safely parses the output. Note how we wrap the json.loads() call to prevent crashes if the model output is unexpectedly truncated.

import json
from openai import OpenAI

client = OpenAI(api_key="your_api_key")

try:
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {
                "role": "system", 
                "content": "Extract user details into a JSON object with keys: 'name', 'age', 'city'."
            },
            {
                "role": "user", 
                "content": "I'm Sarah, a 32-year-old engineer from Seattle."
            }
        ],
        response_format={"type": "json_object"}
    )

    # Convert the string output into a real dictionary
    raw_content = response.choices[0].message.content
    data = json.loads(raw_content)
    print(f"Parsed Data: {data}")

except Exception as e:
    print(f"Failed to process request: {e}")

Essential Verification Checklist

Before moving to production, verify your implementation with these three checks:

- **HTTP 200 OK:** If you see 400, double-check that the literal word "json" appears in your `messages` array.
- **Finish Reason:** Look at `response.choices[0].finish_reason`. If it says `length`, the model ran out of tokens and the JSON is likely broken. It should ideally be `stop`.
- **The Better Alternative:** For 100% schema reliability, consider using **Structured Outputs** (`response_format: { type: "json_schema", ... }`). This newer feature doesn't require you to mention "json" in the prompt and guarantees the output matches your exact keys and data types.

Development Tips

Getting JSON right can be tricky. Even with JSON mode, the model might occasionally add trailing commas or miss a closing bracket if it hits a limit. I always use a tool like the JSON Formatter & Validator at ToolCraft during my debugging phase. It helps visualize nested structures and catches syntax errors that are hard to spot in a messy terminal log.

Remember: JSON mode is available on gpt-4o, gpt-4-turbo, and gpt-3.5-turbo-1106 (or newer). If you try to use it with gpt-4 (the original) or older models, the API will ignore the parameter or error out.

Related Error Notes