Claude API Error 400 invalid_request_error Fix

Written by Michael Lip · Solo founder of Zovo · $400K+ on Upwork · 100% JSS Join 50+ builders · More at zovo.one

The 400 invalid_request_error is the most common Claude API error. It means something in your request format or content is wrong. This guide covers every known cause and the fix for each.

The Error

{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "There was an issue with the format or content of your request."
  },
  "request_id": "req_011CSHoEeqs5C35K2UUqR7Fy"
}

Quick Fix

  1. Check that model, max_tokens, and messages are all present in your request.
  2. Verify messages alternate between user and assistant roles.
  3. If using Claude Opus 4.6, remove any prefilled assistant messages (prefill is not supported).

What Causes This

The 400 error covers all request validation failures. The API checks your request format before processing. Common triggers include:

Full Solution

Validate Required Parameters

Every Messages API request needs these three fields:

import anthropic

client = anthropic.Anthropic()

message = client.messages.create(
    model="claude-sonnet-4-6",       # Required: valid model ID
    max_tokens=1024,                  # Required: positive integer
    messages=[                        # Required: non-empty array
        {"role": "user", "content": "Hello, Claude"}
    ]
)

Fix Message Role Alternation

Messages must alternate between user and assistant. Two consecutive user messages will trigger a 400 error:

# WRONG: Two user messages in a row
messages = [
    {"role": "user", "content": "Hello"},
    {"role": "user", "content": "Are you there?"}  # Error!
]

# CORRECT: Alternating roles
messages = [
    {"role": "user", "content": "Hello"},
    {"role": "assistant", "content": "Hi there!"},
    {"role": "user", "content": "Are you there?"}
]

Fix Prefill Not Supported Error

Claude Opus 4.6 does not support prefilling assistant messages. If you send a request with a prefilled last assistant message, you get a 400 invalid_request_error:

# WRONG on Opus 4.6: prefilled assistant message
messages = [
    {"role": "user", "content": "Write JSON"},
    {"role": "assistant", "content": "{"}  # Error on Opus 4.6!
]

# CORRECT: Use output_config instead
message = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Write JSON for a user profile"}],
    output_config={
        "format": {
            "type": "json_schema",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "email": {"type": "string"}
                },
                "required": ["name", "email"],
                "additionalProperties": False
            }
        }
    }
)

Handle Extended Thinking + Tool Use

When using extended thinking with tools, only tool_choice: auto or tool_choice: none is supported:

# WRONG: tool_choice "any" with thinking
message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=16000,
    thinking={"type": "enabled", "budget_tokens": 10000},
    tool_choice={"type": "any"},  # Error!
    tools=[...],
    messages=[...]
)

# CORRECT: Use "auto" with thinking
message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=16000,
    thinking={"type": "enabled", "budget_tokens": 10000},
    tool_choice={"type": "auto"},  # OK
    tools=[...],
    messages=[...]
)

Catch the Error in Code

import anthropic

client = anthropic.Anthropic()

try:
    message = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello"}]
    )
except anthropic.BadRequestError as e:
    print(f"400 Error: {e.message}")
    print(f"Request ID: {e.response.headers.get('request-id')}")
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

try {
  await client.messages.create({
    model: "claude-sonnet-4-6",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello" }]
  });
} catch (err) {
  if (err instanceof Anthropic.BadRequestError) {
    console.log(`400 Error: ${err.message}`);
  }
}

Prevention

  1. Use the SDK: The Python and TypeScript SDKs validate request structure before sending, catching many 400 errors client-side.
  2. Read the error message: The API message field in the error response explains exactly which parameter is invalid.
  3. Include the request_id: Every error response includes a request_id. Include it when contacting Anthropic support.
  4. Check model compatibility: Not all parameters work with all models. Extended thinking requires budget_tokens >= 1024 and budget_tokens < max_tokens.