Graphify-Labs/graphify · error · RuntimeError

Bedrock API error ({code}): {msg}

Error message

Bedrock API error ({code}): {msg}

What it means

Raised when boto3's `client.converse(...)` raises `botocore.exceptions.ClientError`. The message surfaces the AWS error Code and Message (e.g. AccessDeniedException, ValidationException, ThrottlingException, ModelStreamErrorException, ModelNotReadyException). These are service-side rejections of the request: credentials lack bedrock:InvokeModel, the modelId is wrong for the region, the model isn't subscribed/ready, or throughput was throttled.

Source

Thrown at graphify/llm.py:1717

        "bedrock-runtime",
        config=botocore.config.Config(
            read_timeout=_resolve_api_timeout(),
            connect_timeout=10,
            retries={"max_attempts": _resolve_max_retries() + 1, "mode": "adaptive"},
        ),
    )

    try:
        resp = client.converse(
            modelId=model,
            system=[{"text": _extraction_system(deep=deep_mode)}],
            messages=[{"role": "user", "content": _bedrock_content(user_message, images or [])}],
            inferenceConfig=_bedrock_inference_config(max_tokens, model),
        )
    except botocore.exceptions.ClientError as exc:
        code = exc.response["Error"]["Code"]
        msg = exc.response["Error"]["Message"]
        raise RuntimeError(f"Bedrock API error ({code}): {msg}") from exc

    text = _bedrock_response_text(resp, default="{}")
    result = _parse_llm_json(text)
    usage = resp.get("usage", {})
    result["input_tokens"] = usage.get("inputTokens", 0)
    result["output_tokens"] = usage.get("outputTokens", 0)
    result["model"] = model
    result["finish_reason"] = "length" if resp.get("stopReason") == "max_tokens" else "stop"
    if _response_is_hollow(text, result) and result["finish_reason"] != "length":
        print(
            "[graphify] bedrock returned a hollow response; treating as "
            "truncation so adaptive retry can bisect the chunk.",
            file=sys.stderr,
        )
        result["finish_reason"] = "length"
    return result

View on GitHub (pinned to 7fe58b0b0f)

Solutions

  1. Read the (code) in the message: AccessDeniedException → grant bedrock:InvokeModel; ValidationException → fix modelId/inferenceConfig; ThrottlingException → back off and retry with fewer parallel requests.
  2. Verify model access is enabled for the exact model in the exact region (set AWS_REGION/AWS_DEFAULT_REGION accordingly).
  3. Confirm the modelId string matches Bedrock's naming (e.g. anthropic.claude-3-5-sonnet-...:0 or inference-profile ARNs for cross-region).
  4. For throttling, lower concurrency and add retry/backoff around extraction calls.
Defensive patterns

Strategy: try-catch

Try / catch

import time
RETRYABLE = {"ThrottlingException", "ServiceUnavailableException", "ModelStreamErrorException"}
for attempt in range(4):
    try:
        result = extract_files_direct(chunk, root, backend="bedrock")
        break
    except RuntimeError as e:
        code = e.args[0].split("(")[1].split(")")[0] if "(" in e.args[0] else ""
        if code not in RETRYABLE or attempt == 3:
            raise  # AccessDenied / Validation are config bugs — fix, don't retry
        time.sleep(2 ** attempt)

Prevention

When it happens

Trigger: Bedrock Converse calls with (1) an IAM principal missing bedrock:InvokeModel on the model, (2) a modelId not available/subscribed in AWS_REGION (default us-east-1), (3) throttling/overload on on-demand throughput, (4) invalid inference configuration for that model.

Common situations: Forgot to request model access in the Bedrock console; cross-region default (env vars unset so us-east-1 is used but the model lives elsewhere); IAM policy scoped to the wrong ARN; burst traffic on small on-demand quotas during bulk extraction.

Related errors


AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14). Data as JSON: /api/errors/85be689fe6013712. Report an issue: GitHub.