What Happened?
Portkey's Anthropic-compatible /v1/messages endpoint rejects a request body that Anthropic direct accepts.
The incompatibility appears to be cache_control.scope = "global" on a system content block when using Claude Code / Claude Agent SDK prompt caching scope betas.
Observed behavior:
- Direct Anthropic:
200 OK
- Portkey
/v1/messages: 400 invalid_request_error
- Error:
anthropic error: system.1.cache_control.ephemeral.scope: Extra inputs are not permitted
This is breaking Claude Code / Claude Agent SDK traffic routed through Portkey for us.
What Should Have Happened?
Portkey should accept and forward the same Anthropic-compatible request body that Anthropic direct accepts, including cache_control.scope = "global" when the request uses Anthropic's prompt-caching-scope beta.
Relevant Code Snippet
Minimal raw repro:
const body = {
model: 'claude-opus-4-6',
max_tokens: 32,
system: [
{
type: 'text',
text: "You are Claude Code, Anthropic's official CLI for Claude, running within the Claude Agent SDK.",
},
{
type: 'text',
text: 'Session-specific guidance. Reply with ok.',
cache_control: { type: 'ephemeral', scope: 'global' },
},
],
messages: [
{ role: 'user', content: [{ type: 'text', text: 'Reply with ok.' }] },
],
stream: false,
};
const anthropicBeta =
'claude-code-20250219,interleaved-thinking-2025-05-14,context-management-2025-06-27,prompt-caching-scope-2026-01-05,effort-2025-11-24';
Direct Anthropic request:
curl https://api.anthropic.com/v1/messages \
-H 'content-type: application/json' \
-H 'anthropic-version: 2023-06-01' \
-H "anthropic-beta: $ANTHROPIC_BETA" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-d "$BODY"
Result:
{
"status": 200,
"content": [{ "type": "text", "text": "ok" }]
}
Portkey request with a single Anthropic target:
curl https://api.portkey.ai/v1/messages \
-H 'content-type: application/json' \
-H 'authorization: Bearer dummy' \
-H 'anthropic-version: 2023-06-01' \
-H "anthropic-beta: $ANTHROPIC_BETA" \
-H "x-portkey-api-key: $PORTKEY_API_KEY" \
-H 'x-portkey-config: {"strategy":{"mode":"fallback","on_status_codes":[429,500,502,503,529]},"targets":[{"virtual_key":"anthropic-default-prod","override_params":{"model":"claude-opus-4-6"}}]}' \
-d "$BODY"
Result:
{
"error": {
"message": "anthropic error: system.1.cache_control.ephemeral.scope: Extra inputs are not permitted",
"type": "invalid_request_error"
},
"provider": "anthropic"
}
Additional context:
@anthropic-ai/claude-agent-sdk@0.2.89
claude-cli/2.1.89
- This field is emitted by Claude Code / Agent SDK request construction, not by our application prompt builder.
- Portkey docs appear to document
cache_control.type and ttl, but I could not find mention of cache_control.scope.
If helpful, I can provide a fully self-contained Node repro as well.
What Happened?
Portkey's Anthropic-compatible
/v1/messagesendpoint rejects a request body that Anthropic direct accepts.The incompatibility appears to be
cache_control.scope = "global"on a system content block when using Claude Code / Claude Agent SDK prompt caching scope betas.Observed behavior:
200 OK/v1/messages:400 invalid_request_erroranthropic error: system.1.cache_control.ephemeral.scope: Extra inputs are not permittedThis is breaking Claude Code / Claude Agent SDK traffic routed through Portkey for us.
What Should Have Happened?
Portkey should accept and forward the same Anthropic-compatible request body that Anthropic direct accepts, including
cache_control.scope = "global"when the request uses Anthropic's prompt-caching-scope beta.Relevant Code Snippet
Minimal raw repro:
Direct Anthropic request:
Result:
{ "status": 200, "content": [{ "type": "text", "text": "ok" }] }Portkey request with a single Anthropic target:
Result:
{ "error": { "message": "anthropic error: system.1.cache_control.ephemeral.scope: Extra inputs are not permitted", "type": "invalid_request_error" }, "provider": "anthropic" }Additional context:
@anthropic-ai/claude-agent-sdk@0.2.89claude-cli/2.1.89cache_control.typeandttl, but I could not find mention ofcache_control.scope.If helpful, I can provide a fully self-contained Node repro as well.