BerriAI/litellm · error · ValueError
Invalid ARN format
Error message
Invalid ARN format: {arn} What it means
_extract_region_from_arn splits the AgentCore ARN on ':' and requires at least 4 parts so that parts[3] (the region) exists. This ValueError is raised when the value after 'agentcore/' is a truncated ARN or a bare runtime identifier — e.g. 'arn:aws:bedrock-agentcore' (3 parts) or 'my-runtime-id' (1 part). It is the second format gate after the prefix check.
Solutions
- Pass the full runtime ARN after the prefix: agentcore/arn:aws:bedrock-agentcore:region:account:runtime/runtime-id
- Validate the ARN has at least 6 colon-separated fields and starts with arn:aws:bedrock-agentcore: before calling litellm
- Check env/YAML templates for empty region or account substitutions that silently shrink the ARN
Example fix
// before model = "agentcore/hosted_agent_r9jvp-3ySZuRHjLC" // bare runtime id // after model = "agentcore/arn:aws:bedrock-agentcore:us-west-2:888602223428:runtime/hosted_agent_r9jvp-3ySZuRHjLC"
Defensive patterns
Strategy: validation
Validate before calling
def assert_full_agentcore_arn(model: str) -> None:
arn = model.split("/", 1)[1] if model.startswith("agentcore/") else model
parts = arn.split(":")
if len(parts) < 6 or not parts[3]:
raise ValueError(f"Not a full AgentCore runtime ARN (need >=6 colon fields): {arn!r}")
assert_full_agentcore_arn(model)
resp = litellm.completion(model=model, messages=msgs) Type guard
def is_full_agentcore_arn(arn: str) -> bool:
"""True when arn has a region field and the full 6+ part structure."""
parts = arn.split(":")
return len(parts) >= 6 and bool(parts[3]) Try / catch
try:
resp = litellm.completion(model=model, messages=msgs)
except ValueError as e:
if "Invalid ARN format" in str(e):
raise ConfigError(f"AgentCore model must carry the full runtime ARN: {model!r}") from e
raise Prevention
- Always pass the console-rendered ARN, not the runtime display name
- Lint env-var templates so empty region/account substitutions fail CI
- Test ARN length/field count when loading config
When it happens
Trigger: model="agentcore/hosted_agent_xyz" (bare runtime id instead of the ARN); an ARN copy-pasted but truncated at the account or service field; CI/CD or env-var interpolation that drops the colon-separated fields; a template with empty {region} that collapses the ARN.
Common situations: Using the friendly runtime name shown in the console list view instead of its ARN; long ARNs mangled by YAML folding or shell truncation; building ARNs from templates whose region/account variables are empty.
Related errors
- Invalid model format. Expected format…
- Invalid region in ARN
- Invalid model format. Expected format…
- AgentCore: Failed to read/parse JSON response body
- Bedrock batch embedding `input` must be a string (or a…
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/a7ad26f75d090589.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/llms/bedrock/chat/agentcore/transformation.py:177
returns: "arn:aws:bedrock-agentcore:us-west-2:888602223428:runtime/hosted_agent_r9jvp-3ySZuRHjLC"
"""
parts: Final = model.split("/", 1)
if len(parts) != 2 or parts[0] != "agentcore":
raise ValueError(
"Invalid model format. Expected format: 'model=bedrock/agentcore/arn:aws:bedrock-agentcore:region:account:runtime/runtime_id'"
)
return parts[1]
def _extract_region_from_arn(self, arn: str) -> str:
"""
Extract region from ARN
arn:aws:bedrock-agentcore:us-west-2:888602223428:runtime/hosted_agent_r9jvp-3ySZuRHjLC
returns: us-west-2
"""
parts: Final = arn.split(":")
if len(parts) >= 4:
return parts[3]
raise ValueError(f"Invalid ARN format: {arn}")
def _get_runtime_session_id(self, optional_params: dict) -> str:
"""
Get or generate runtime session ID (must be 33+ chars)
"""
session_id: Final = optional_params.get("runtimeSessionId", None)
if session_id:
verbose_logger.debug("Using provided runtimeSessionId: %s", session_id)
return session_id
# Generate a session ID with 33+ characters
generated_id: Final = f"litellm-session-{uuid.uuid4()}"
verbose_logger.debug("Generated new session ID: %s", generated_id)
return generated_id
def _get_runtime_user_id(self, optional_params: dict) -> str | None:
"""
Get runtime user ID if providedView on GitHub (pinned to 77b7c6c40c)