BerriAI/litellm · error · ValueError

Invalid region in ARN

Error message

Invalid region in ARN: {batch_id}

What it means

Thrown by LiteLLM's Bedrock batch retrieval (get_batch) before any HTTP call is made. The batch_id must be the full model-invocation-job ARN returned by the create-batch call; the code splits it on ':' and validates field 4 (the region) against the regex ^[a-z][a-z0-9-]*$. If the region slot is empty or malformed, the lookup is rejected with this ValueError so no request is signed against a bogus endpoint.

Solutions

  1. Pass the exact jobArn returned by the create-batch call (the id on LiteLLM's Batch object) — treat it as an opaque string, do not reconstruct it
  2. If you must build the ARN, verify all 6+ colon fields are present and the region is lowercase letters/digits/hyphens starting with a letter (e.g. us-west-2)
  3. Log the batch_id immediately before the call and diff it against the ARN shown in the AWS Bedrock console under Model invocation jobs
  4. If the id came from an older LiteLLM create response that returned a short id, re-create the batch or upgrade LiteLLM so retrieval uses the ARN form

Example fix

// before
batch_id = "arn:aws:bedrock:::model-invocation-job/inference-170"
result = litellm.batch_get(provider="bedrock", batch_id=batch_id)

// after
batch_id = "arn:aws:bedrock:us-west-2:123456789012:model-invocation-job/inference-170"
result = litellm.batch_get(provider="bedrock", batch_id=batch_id)
Defensive patterns

Strategy: validation

Validate before calling

import re

BATCH_ARN_RE = re.compile(r"^arn:aws:bedrock:[a-z][a-z0-9-]*:\d{12}:model-invocation-job/.+$")

if not BATCH_ARN_RE.match(batch_id):
    raise ValueError(f"Refusing to call batch_get: malformed ARN {batch_id!r}")
result = litellm.batch_get(provider="bedrock", batch_id=batch_id)

Type guard

def is_valid_bedrock_batch_arn(batch_id: str) -> bool:
    """True only for well-formed Bedrock model-invocation-job ARNs."""
    return bool(re.match(r"^arn:aws:bedrock:[a-z][a-z0-9-]*:\d{12}:model-invocation-job/.+$", batch_id))

Try / catch

try:
    result = litellm.batch_get(provider="bedrock", batch_id=batch_id)
except ValueError as e:
    if "Invalid region in ARN" in str(e):
        raise ConfigError(f"Stored batch id is not a valid ARN: {batch_id!r}") from e
    raise

Prevention

When it happens

Trigger: Calling litellm.batch_get/aget_batch with provider="bedrock" and a batch_id whose ARN region slot is empty (arn:aws:bedrock:::model-invocation-job/x — leftover colons), starts with a digit or underscore, contains uppercase letters (arn:aws:bedrock:US-West-2:...), or where a hand-assembled ARN put a non-region value in position 3.

Common situations: Hand-templating the ARN instead of copying jobArn from the create-batch response; string surgery that drops the region; environment-variable templates with an empty {region}; migrating batch ids from another system that stored short job names or partial ARNs.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/508fce7c1acc1d26. Report an issue: GitHub.

Appendix: source

Thrown at litellm/llms/bedrock/batches/transformation.py:385

            litellm_params: LiteLLM parameters

        Returns:
            Transformed request data for Bedrock GetModelInvocationJob API
        """
        # For Bedrock, batch_id should be the full job ARN
        # The GetModelInvocationJob API expects the full ARN as the identifier
        if not batch_id.startswith("arn:aws:bedrock:"):
            raise ValueError(f"Invalid batch_id format. Expected ARN, got: {batch_id}")

        # Extract the job identifier from the ARN - use the full ARN path part
        # ARN format: arn:aws:bedrock:region:account:model-invocation-job/job-name
        arn_parts: Final = batch_id.split(":")
        if len(arn_parts) < 6:
            raise ValueError(f"Invalid ARN format: {batch_id}")

        region: Final = arn_parts[3]
        if not re.match(r"^[a-z][a-z0-9-]*$", region):
            raise ValueError(f"Invalid region in ARN: {batch_id}")

        # Build the endpoint URL for GetModelInvocationJob
        # AWS API format: GET /model-invocation-job/{jobIdentifier}
        # Use the FULL ARN as jobIdentifier and URL-encode it (includes ':' and '/')
        import urllib.parse as _ul

        encoded_arn: Final = _ul.quote(batch_id, safe="")
        endpoint_url: Final = f"https://bedrock.{region}.amazonaws.com/model-invocation-job/{encoded_arn}"

        # Use common utility for AWS signing
        request_params: Final = merge_bedrock_aws_request_params(litellm_params, optional_params)
        signed_headers, _ = self.common_utils.sign_aws_request(
            service_name="bedrock",
            data={},  # GET request has no body
            endpoint_url=endpoint_url,
            optional_params=request_params,
            method="GET",
        )

View on GitHub (pinned to 77b7c6c40c)