claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] Task tool subagents don't inherit EU cross-region inference model configuration for AWS Bedrock

Open xmnlp opened this issue 2 months ago โ€ข 6 comments

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When using AWS Bedrock with EU cross-region inference models (model ID format: eu.anthropic.claude-sonnet-4-5-20250929-v1:0), the Task tool fails to launch subagents because it attempts to use the standard US model ID format (anthropic.claude-sonnet-4-5-20250929-v1:0) instead of inheriting the configured EU model ID.

This results in a 403 authentication error because the AWS IAM role has access to the EU cross-region model but not the US format model.

What Should Happen?

The Task tool should inherit the configured model ID (eu.anthropic.claude-sonnet-4-5-20250929-v1:0) and successfully launch subagents using the same model configuration as the main conversation.

Error Messages/Logs

API Error: 403 {"Message":"User: arn:aws:sts::xxxxx:assumed-role/xxxxx/[email protected] is
not authorized to perform: bedrock:InvokeModel on resource: arn:aws:bedrock:::foundation-model/anthropic.claude-sonnet-4-5-20250929-v1:0 with an
explicit deny in a service control policy"} ยท Please run /login

Steps to Reproduce

  1. Configure Claude Code to use AWS Bedrock in eu-central-1 region
  2. Set model to: eu.anthropic.claude-sonnet-4-5-20250929-v1:0 (EU cross-region inference format)
  3. Verify main conversation works (it does, I can interact normally)
  4. Attempt to launch a subagent using the Task tool with any subagent_type (e.g., general-purpose, Explore)
  5. Observe the 403 error

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

No response

Claude Code Version

2.0.37 (Claude Code)

Platform

AWS Bedrock

Operating System

macOS

Terminal/Shell

iTerm2

Additional Information

No response

xmnlp avatar Nov 12 '25 14:11 xmnlp


Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/10807
  2. https://github.com/anthropics/claude-code/issues/8932
  3. https://github.com/anthropics/claude-code/issues/4855

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and ๐Ÿ‘ the existing issue instead
  • To prevent auto-closure, add a comment or ๐Ÿ‘Ž this comment

๐Ÿค– Generated with Claude Code


github-actions[bot] avatar Nov 12 '25 15:11 github-actions[bot]

While they share similar themes around subagent configuration inheritance, I'd say this is (probably) a distinct bug:

  • #10807: Gets 400 "invalid model identifier" (hardcoded us. prefix)
  • #8932: Model selection inheritance (Sonnet vs Opus) on Anthropic API
  • #4855: AWS credential propagation failure
  • This issue: Gets 403 auth error because subagents use standard US format (anthropic.claude-*) instead of the configured EU cross-region format (eu.anthropic.claude-*)

The error codes and failure modes are different enough that these may require separate fixes, even if they share a common root cause around configuration inheritance.

xmnlp avatar Nov 12 '25 16:11 xmnlp

Possible Root Cause

I inspected the compiled cli.js and found what might be causing this issue.

Around line 497, there appear to be hardcoded model definitions:

TJ1 = {
  firstParty: "claude-sonnet-4-5-20250929",
  bedrock: "us.anthropic.claude-sonnet-4-5-20250929-v1:0",
  ...
}

qJA = {
  firstParty: "claude-haiku-4-5-20251001",
  bedrock: "us.anthropic.claude-haiku-4-5-20251001-v1:0",
  ...
}

It looks like Task tool subagents may be using these hardcoded us.anthropic.* model IDs instead of respecting the ANTHROPIC_MODEL and ANTHROPIC_SMALL_FAST_MODEL environment variables that work for the main agent.

Why This Would Explain the Issue

  • โœ… Main agent works โ€” uses env vars โ†’ eu.anthropic.* format
  • โŒ Subagents fail โ€” uses hardcoded IDs โ†’ us.anthropic.* format โ†’ 403 in EU

Attempted Workarounds (None Worked)

  • Setting AWS_REGION=eu-central-1
  • Setting ANTHROPIC_MODEL=eu.anthropic.claude-sonnet-4-5-20250929-v1:0
  • Setting ANTHROPIC_SMALL_FAST_MODEL=eu.anthropic.claude-haiku-4-5-20251001-v1:0

Suggested Fix

If this is the issue, the Task tool should respect these environment variables when selecting models for subagents.

xmnlp avatar Nov 12 '25 17:11 xmnlp

Summary

I used Claude Code to help me analyze bug #11489, and this is what I arrived at:

Task tool subagents fail when using AWS Bedrock in EU regions (eu-central-1) due to hardcoded model IDs that don't support cross-region inference profiles. The main Claude Code agent respects the ANTHROPIC_MODEL environment variable, but Task subagents ignore environment variables and use hardcoded model identifiers that are either:

  1. Prefixed with us.anthropic.* (blocked by AWS Service Control Policies restricting non-EU regions)
  2. Prefixed with plain anthropic.* (defaults to us-east-1, also blocked)
  3. Non-existent in EU cross-region profiles (e.g., claude-3-5-haiku-20241022)

Environment

AWS_REGION=eu-central-1
ANTHROPIC_MODEL=eu.anthropic.claude-sonnet-4-5-20250929-v1:0
ANTHROPIC_SMALL_FAST_MODEL=eu.anthropic.claude-haiku-4-5-20251001-v1:0
CLAUDE_CODE_USE_BEDROCK=1
AWS_PROFILE=[YOUR_AWS_PROFILE]

Claude Code Version: 2.0.37 Installation: Homebrew (also tested with npm) Platform: macOS (Darwin 24.6.0)

Issue Details

Main Agent vs Task Subagents Behavior

Component Respects Env Vars Model ID Used Result
Main Agent โœ… Yes eu.anthropic.claude-sonnet-4-5-20250929-v1:0 โœ… Works
Task Subagent (haiku) โŒ No us.anthropic.claude-3-5-haiku-20241022-v1:0 โŒ 400 error
Task Subagent (sonnet) โŒ No anthropic.claude-sonnet-4-5-20250929-v1:0 โŒ 403 error

Error Messages

With model=haiku:

API Error (us.anthropic.claude-3-5-haiku-20241022-v1:0): 400 The provided model identifier is invalid.

With model=sonnet:

403 not authorized to perform: bedrock:InvokeModel on resource:
arn:aws:bedrock:::foundation-model/anthropic.claude-sonnet-4-5-20250929-v1:0

Investigation & Root Cause Analysis

1. Hardcoded Model IDs in Binary

By examining the compiled binary with strings, we identified hardcoded model ID definitions:

// Found in cli.js (compiled binary)
var l6T = O(() => {
  v6T = {firstParty:"claude-3-7-sonnet-20250219", bedrock:"us.anthropic.claude-3-7-sonnet-20250219-v1:0", vertex:"claude-3-7-sonnet@20250219"},
  g6T = {firstParty:"claude-3-5-sonnet-20241022", bedrock:"anthropic.claude-3-5-sonnet-20241022-v2:0", vertex:"claude-3-5-sonnet-v2@20241022"},
  d6T = {firstParty:"claude-3-5-haiku-20241022", bedrock:"us.anthropic.claude-3-5-haiku-20241022-v1:0", vertex:"claude-3-5-haiku@20241022"},
  c6T = {firstParty:"claude-haiku-4-5-20251001", bedrock:"us.anthropic.claude-haiku-4-5-20251001-v1:0", vertex:"claude-haiku-4-5@20251001"},
  yp = {firstParty:"claude-sonnet-4-20250514", bedrock:"us.anthropic.claude-sonnet-4-20250514-v1:0", vertex:"claude-sonnet-4@20250514"},
  n5R = {firstParty:"claude-sonnet-4-5-20250929", bedrock:"us.anthropic.claude-sonnet-4-5-20250929-v1:0", vertex:"claude-sonnet-4-5@20250929"},
  u6T = {firstParty:"claude-opus-4-20250514", bedrock:"us.anthropic.claude-opus-4-20250514-v1:0", vertex:"claude-opus-4@20250514"},
  m6T = {firstParty:"claude-opus-4-1-20250805", bedrock:"us.anthropic.claude-opus-4-1-20250805-v1:0", vertex:"claude-opus-4-1@20250805"}
});

Key findings:

  • Most models use us.anthropic.* prefix (7 models)
  • Claude 3.5 Sonnet uses plain anthropic.* prefix (no region)
  • No EU-specific model IDs in the codebase
  • Environment variables are not checked for Task subagent model selection

2. Available EU Cross-Region Models

We verified which models exist in eu-central-1:

aws bedrock list-inference-profiles --region eu-central-1

Available with eu.anthropic.* prefix:

  • โœ… eu.anthropic.claude-3-haiku-20240307-v1:0 (old haiku 3.0)
  • โœ… eu.anthropic.claude-haiku-4-5-20251001-v1:0 (new haiku 4.5)
  • โœ… eu.anthropic.claude-3-sonnet-20240229-v1:0
  • โœ… eu.anthropic.claude-3-5-sonnet-20240620-v1:0
  • โœ… eu.anthropic.claude-3-7-sonnet-20250219-v1:0
  • โœ… eu.anthropic.claude-sonnet-4-20250514-v1:0
  • โœ… eu.anthropic.claude-sonnet-4-5-20250929-v1:0

NOT available in EU:

  • โŒ eu.anthropic.claude-3-5-haiku-20241022-v1:0 (doesn't exist)

3. Model ID Prefix Behavior

Prefix Behavior Works in EU with SCP?
us.anthropic.* Explicit US cross-region โŒ No (403 - blocked by SCP)
anthropic.* Defaults to us-east-1 โŒ No (403 - blocked by SCP)
eu.anthropic.* Explicit EU cross-region โœ… Yes

Attempted Workarounds

Workaround 1: Binary Patching (Partial Success)

We attempted to patch the compiled binary by replacing string literals:

# This works (same length strings):
perl -pi -e 's/us\.anthropic\.claude/eu.anthropic.claude/g' claude
codesign -s - -f claude

Results:

  • โœ… Successfully patched 7 models with us.anthropic.* prefix
  • โŒ Cannot patch anthropic.* โ†’ eu.anthropic.* (3 character length difference corrupts binary)
  • โŒ Cannot fix runtime model ID construction
  • โŒ Cannot make non-existent models (haiku 3.5) magically exist

Workaround 2: Environment Variables (Not Respected)

Setting ANTHROPIC_SMALL_FAST_MODEL has no effect on Task subagents:

export ANTHROPIC_SMALL_FAST_MODEL=eu.anthropic.claude-haiku-4-5-20251001-v1:0

Task subagents still use hardcoded us.anthropic.claude-3-5-haiku-20241022-v1:0.

Test Results Summary

Test # Binary Used Model Param Attempted Model ID Error Duration
1 npm (unpatched) haiku us.anthropic.claude-3-5-haiku-20241022-v1:0 400 ~1s
2 Homebrew (patched) haiku eu.anthropic.claude-3-5-haiku-20241022-v1:0 400 ~1s
3 Homebrew (patched) sonnet anthropic.claude-sonnet-4-5-20250929-v1:0 403 3m 11s

Recommended Upstream Fixes

Option 1: Respect Environment Variables (Preferred)

Task subagents should respect the same environment variables as the main agent:

// Pseudocode
function getModelForSubagent(modelType) {
  if (process.env.ANTHROPIC_SMALL_FAST_MODEL && modelType === 'haiku') {
    return process.env.ANTHROPIC_SMALL_FAST_MODEL;
  }
  if (process.env.ANTHROPIC_MODEL) {
    return process.env.ANTHROPIC_MODEL;
  }
  // Fall back to defaults
  return getDefaultModel(modelType);
}

Option 2: Detect AWS Region Automatically

// Pseudocode
function getModelPrefix() {
  const region = process.env.AWS_REGION || 'us-east-1';

  if (region.startsWith('eu-')) {
    return 'eu.anthropic';
  } else if (region.startsWith('us-')) {
    return 'us.anthropic';
  }
  // Default to plain anthropic. for backwards compatibility
  return 'anthropic';
}

Option 3: Configuration File

Add a .claude-code.config.json or similar:

{
  "bedrock": {
    "modelPrefix": "eu.anthropic",
    "defaultHaiku": "eu.anthropic.claude-haiku-4-5-20251001-v1:0",
    "defaultSonnet": "eu.anthropic.claude-sonnet-4-5-20250929-v1:0"
  }
}

Option 4: Update Default Model Definitions

For Bedrock deployments, use region-aware model IDs:

// Instead of hardcoding us.anthropic or plain anthropic:
const SONNET_45 = {
  firstParty: "claude-sonnet-4-5-20250929",
  bedrock: detectBedrockModelId("claude-sonnet-4-5-20250929"), // Auto-detects region
  vertex: "claude-sonnet-4-5@20250929"
};

Additional Observations

Non-Existent Models in EU

The default haiku model (claude-3-5-haiku-20241022) doesn't exist in EU cross-region profiles. EU users should use:

  • eu.anthropic.claude-haiku-4-5-20251001-v1:0 (Haiku 4.5) - Recommended
  • eu.anthropic.claude-3-haiku-20240307-v1:0 (Haiku 3.0) - Legacy

Service Control Policy Context

Many AWS organizations use SCPs to restrict cross-region data transfer. A common policy:

{
  "Effect": "Deny",
  "Action": "bedrock:InvokeModel",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:RequestedRegion": ["eu-central-1", "eu-west-1"]
    }
  }
}

This makes us.anthropic.* and plain anthropic.* prefixes unusable in EU-only environments.

Impact

Severity: High Affected Users: All AWS Bedrock users in EU regions with restrictive SCPs Workaround: None that fully works Feature Impact: Task tool (Explore, Plan, other subagents) completely non-functional

Reproduction Steps

  1. Set up AWS Bedrock in EU region (e.g., eu-central-1)
  2. Apply SCP restricting Bedrock to EU regions only
  3. Configure Claude Code with EU cross-region model:
    export AWS_REGION=eu-central-1
    export ANTHROPIC_MODEL=eu.anthropic.claude-sonnet-4-5-20250929-v1:0
    export CLAUDE_CODE_USE_BEDROCK=1
    
  4. Start Claude Code - main agent works fine โœ…
  5. Try to use Task tool with any subagent - fails with 403 or 400 โŒ

Files Analyzed

  • /opt/homebrew/Caskroom/claude-code/2.0.37/claude (Homebrew binary)
  • $HOME/.nvm/versions/node/v22.18.0/lib/node_modules/@anthropic-ai/claude-code/cli.js (npm binary)
  • Both contain identical hardcoded model definitions

Conclusion

The Task tool subagents in Claude Code 2.0.37 have hardcoded US-region Bedrock model IDs that cannot be overridden via environment variables. This makes the Task tool completely unusable for AWS Bedrock deployments in EU regions with restrictive Service Control Policies.

While binary patching can partially work around this issue, it has fundamental limitations (string length constraints, runtime model construction, non-existent models) that make it unsuitable as a long-term solution.

An upstream fix is required to make Claude Code's Task tool compatible with AWS Bedrock cross-region inference profiles outside of the US.


xmnlp avatar Nov 12 '25 19:11 xmnlp

I'm getting a similar error running the command /context:

IHA [Error]: 400 The provided model identifier is invalid.
    at V9.generate (file:///Users/andrius/.nvm/versions/node/v22.20.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:121:10380)
    at eeA.makeStatusError (file:///Users/andrius/.nvm/versions/node/v22.20.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:1283:2195)
    at eeA.makeRequest (file:///Users/andrius/.nvm/versions/node/v22.20.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:1283:5420)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async K12 (file:///Users/andrius/.nvm/versions/node/v22.20.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:1435:3423)
    at async cjA (file:///Users/andrius/.nvm/versions/node/v22.20.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:2218:95)
    at async Promise.all (index 2)
    at async ra5 (file:///Users/andrius/.nvm/versions/node/v22.20.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:2218:406)
    at async Promise.all (index 0)
    at async qh2 (file:///Users/andrius/.nvm/versions/node/v22.20.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:2218:2655) {
  status: 400,
  headers: Headers {},
  requestID: null,
  error: { message: 'The provided model identifier is invalid.' }
}

Node.js v22.20.0

When using a model on AWS Bedrock:

export AWS_REGION=eu-central-1
export ANTHROPIC_MODEL='eu.anthropic.claude-sonnet-4-5-20250929-v1:0'

andrius-senulis avatar Dec 09 '25 10:12 andrius-senulis

@bcherny how to proceed? I would love to see this fixed for my EU-bound organisation.

AlbertBrand avatar Dec 23 '25 11:12 AlbertBrand