openclaw - ✅(Solved) Fix [Bug]: `image` tool fails for Bedrock with `auth mode: aws-sdk` — `requireApiKey` throws even when AWS SDK creds are available [2 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#72031Fetched 2026-04-27 05:35:53
View on GitHub
Comments
2
Participants
3
Timeline
7
Reactions
0
Timeline (top)
commented ×2cross-referenced ×2referenced ×2labeled ×1

The image tool (media-understanding image-description path) always requires an explicit apiKey when resolving provider auth. For amazon-bedrock using IAM role / instance profile / AWS_PROFILE credentials (i.e. ResolvedProviderAuth.mode === "aws-sdk"), no static API key exists — the AWS SDK resolves credentials at call time. The chat/completion path handles this correctly via an allowMissingApiKeyModes escape hatch; the image path does not, and throws before the Bedrock call is ever made.

Net effect: every image analysis against a Bedrock model fails, even when chat against the same model works fine.

Affected models tested (all fail identically)

  • amazon-bedrock/us.anthropic.claude-opus-4-7
  • amazon-bedrock/us.anthropic.claude-sonnet-4-6
  • amazon-bedrock/us.amazon.nova-pro-v1:0
  • amazon-bedrock/stability.stable-image-ultra-v1:1 (same provider, same failure)

Error Message

// src/agents/simple-completion-runtime.ts (around L182-L194) if ( !rawApiKey && !hasMissingApiKeyAllowance({ mode: auth.mode, allowMissingApiKeyModes: params.allowMissingApiKeyModes }) ) { return { error: No API key resolved for provider "${resolved.model.provider}" (auth mode: ${auth.mode})., auth }; }

Root Cause

Root Cause:

Fix Action

Fixed

PR fix notes

PR #72066: fix(media-understanding): allow aws-sdk auth mode in image tool [AI-assisted]

Description (problem / solution / changelog)

🤖 AI-assisted (built with Claude Code via Hermes orchestration). Test level: fully tested. Prompt summary available on request.

Summary

  • Problem: The image tool fails for all Bedrock models when using AWS SDK credential resolution (IAM role, instance profile, AWS_PROFILE). requireApiKey throws No API key resolved for provider "amazon-bedrock" (auth mode: aws-sdk) even though chat/completion with the same model works fine.
  • Why it matters: Any user relying on AWS SDK credential chains (the standard for IAM roles, EC2 instances, ECS tasks) cannot use image analysis with Bedrock models at all.
  • What changed: Added requireApiKeyAllowAwsSdk helper in model-auth-runtime-shared.ts that returns an empty string for aws-sdk mode instead of throwing. Replaced requireApiKey calls in image.ts (2 sites) and runner.entries.ts (1 site) with the new helper.
  • What did NOT change (scope boundary): requireApiKey itself is unchanged — all non-aws-sdk auth modes still throw on missing keys. The chat/completion path's existing allowMissingApiKeyModes mechanism is untouched.

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • Media understanding (src/media-understanding/)
  • Agent auth (src/agents/model-auth*)

Linked Issue/PR

  • Closes #72031
  • This PR fixes a bug or regression

Root Cause

  • Root cause: resolveImageRuntime in image.ts unconditionally called requireApiKey, which throws when auth.apiKey is empty regardless of auth.mode. For amazon-bedrock with aws-sdk mode, no static API key exists — the AWS SDK resolves credentials at call time. The chat path already handled this via allowMissingApiKeyModes: ["aws-sdk"], but the image path did not.
  • Missing detection / guardrail: No test covered the aws-sdk auth mode path in the image tool.
  • Contributing context: The image tool auth was written before Bedrock's aws-sdk credential mode was widely used, and the escape hatch was only added to the chat path.

Regression Test Plan

  • Coverage level that should have caught this:
    • Unit test
  • Target test or file: src/media-understanding/image.test.ts
  • Scenario the test should lock in: describeImageWithModel with auth.mode === "aws-sdk" and no API key must succeed without throwing.
  • Why this is the smallest reliable guardrail: Direct unit test on the image description function with mocked aws-sdk auth — no AWS credentials needed.
  • Existing test that already covers this: N/A

User-visible / Behavior Changes

Image analysis with Bedrock models using AWS SDK credentials now works (previously always failed).

Diagram (if applicable)

N/A

Security Impact (required)

  • New permissions/capabilities? No
  • requireApiKeyAllowAwsSdk only relaxes the API key requirement for aws-sdk mode, which by definition uses the AWS SDK credential chain instead of static keys. All other auth modes still require an explicit API key. The empty string passed as apiKey is not used by the Bedrock SDK path — it resolves credentials independently.

Changed files

  • src/agents/model-auth-runtime-shared.ts (modified, +7/-0)
  • src/agents/model-auth.test.ts (modified, +2/-0)
  • src/agents/model-auth.ts (modified, +5/-1)
  • src/media-understanding/image.test.ts (modified, +51/-1)
  • src/media-understanding/image.ts (modified, +3/-3)
  • src/media-understanding/runner.entries.ts (modified, +2/-2)

PR #72092: fix(media): allow aws-sdk auth mode for image and audio/video paths

Description (problem / solution / changelog)

The chat path's prepareSimpleCompletionModel exposes an allowMissingApiKeyModes escape hatch so providers whose auth.mode === "aws-sdk" (notably amazon-bedrock) can resolve credentials at call time via the AWS SDK chain instead of a static apiKey. The image and audio/video runtime paths in media-understanding did not have the same escape: each one unconditionally called requireApiKey, which throws on an empty key, so the image/audio/video tools failed for Bedrock deployments using BYOK with role/SSO/profile credentials.

This patches the three sites in media-understanding that resolve a primary api key:

  • resolveImageRuntime (src/media-understanding/image.ts:202-211)
  • resolveMinimaxVlmFallbackRuntime (src/media-understanding/image.ts:308-313)
  • resolveProviderExecutionAuth (src/media-understanding/runner.entries.ts:401-411)

Each site now follows the same shape: when the resolved auth key is empty and the auth mode is aws-sdk, the api key is passed through as "" (the SDK resolves credentials at call time); otherwise requireApiKey runs and the existing throw semantics are preserved for every other auth mode. The image runtime also skips setRuntimeApiKey for the empty-key aws-sdk case so we don't write empty-string secrets into runtime auth storage.

Adds a regression test covering the aws-sdk amazon-bedrock image describe path: requireApiKey is not called, setRuntimeApiKey is not called, and the underlying complete() is invoked with apiKey: "" so the AWS SDK auth chain takes over.

Closes #72031.

AI-assisted

  • Lightly tested. New test covers the image describe path on amazon-bedrock + aws-sdk. Targeted media-understanding files run clean: image.test.ts 12/12, runtime.test.ts + runner.video.test.ts + runner.cli-audio.test.ts 18/18, runner.entries.guards.test.ts + runner.proxy.test.ts + runner.auto-audio.test.ts + runner.deepgram.test.ts 14/14. Did not run a Bedrock instance end-to-end.
  • I understand the change. The chat path landed an allowMissingApiKeyModes parameter when aws-sdk auth was first added (so the AWS SDK chain can resolve creds itself). The three media-understanding sites resolve auth via a shared helper but never carry the missing-key allowance through to requireApiKey. The fix is the narrowest equivalent: bypass requireApiKey when the resolved key is empty and the mode is aws-sdk, leave the throw in place for every other case.

Changed files

  • src/agents/api-key-rotation.ts (modified, +8/-0)
  • src/media-understanding/image.test.ts (modified, +53/-0)
  • src/media-understanding/image.ts (modified, +10/-3)
  • src/media-understanding/runner.aws-sdk.test.ts (added, +172/-0)
  • src/media-understanding/runner.entries.ts (modified, +24/-17)

Code Example

image(image="/path/to/test.png", model="sonnet", prompt="What is in this image?")

---

All image models failed (2): amazon-bedrock/us.anthropic.claude-sonnet-4-6:
  No API key resolved for provider "amazon-bedrock" (auth mode: aws-sdk).
  | amazon-bedrock/us.amazon.nova-pro-v1:0:
  No API key resolved for provider "amazon-bedrock" (auth mode: aws-sdk).

---

// src/media-understanding/image.ts (around L197-L206)
const apiKeyInfo = await getApiKeyForModel({ model, ... });
const apiKey = requireApiKey(apiKeyInfo, model.provider);   // throws for aws-sdk
authStorage.setRuntimeApiKey(model.provider, apiKey);
return { apiKey, model };

---

export function requireApiKey(auth: ResolvedProviderAuth, provider: string): string {
  const key = normalizeSecretInput(auth.apiKey);
  if (key) return key;
  throw new Error(`No API key resolved for provider "${provider}" (auth mode: ${auth.mode}).`);
}

---

// src/agents/simple-completion-runtime.ts (around L182-L194)
if (
  !rawApiKey &&
  !hasMissingApiKeyAllowance({ mode: auth.mode, allowMissingApiKeyModes: params.allowMissingApiKeyModes })
) {
  return { error: `No API key resolved for provider "${resolved.model.provider}" (auth mode: ${auth.mode}).`, auth };
}

---

// src/media-understanding/image.ts :: resolveImageRuntime
const apiKeyInfo = await getApiKeyForModel({ model, ... });
const rawApiKey = apiKeyInfo.apiKey?.trim();
if (!rawApiKey && apiKeyInfo.mode !== "aws-sdk") {
  requireApiKey(apiKeyInfo, model.provider); // preserves existing error for non-aws-sdk
}
const apiKey = rawApiKey ?? "";
if (apiKey) authStorage.setRuntimeApiKey(model.provider, apiKey);
return { apiKey, model };

---
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

The image tool (media-understanding image-description path) always requires an explicit apiKey when resolving provider auth. For amazon-bedrock using IAM role / instance profile / AWS_PROFILE credentials (i.e. ResolvedProviderAuth.mode === "aws-sdk"), no static API key exists — the AWS SDK resolves credentials at call time. The chat/completion path handles this correctly via an allowMissingApiKeyModes escape hatch; the image path does not, and throws before the Bedrock call is ever made.

Net effect: every image analysis against a Bedrock model fails, even when chat against the same model works fine.

Affected models tested (all fail identically)

  • amazon-bedrock/us.anthropic.claude-opus-4-7
  • amazon-bedrock/us.anthropic.claude-sonnet-4-6
  • amazon-bedrock/us.amazon.nova-pro-v1:0
  • amazon-bedrock/stability.stable-image-ultra-v1:1 (same provider, same failure)

Steps to reproduce

  1. Configure a Bedrock-backed model as the image model, with credentials provided via AWS SDK chain (IAM role, instance profile, or AWS_PROFILE) — no static AWS_BEARER_TOKEN_BEDROCK or API-key-style credential.

  2. Confirm chat works (openclaw chat ... with a Bedrock model returns text).

  3. Invoke the image tool from any agent, e.g.:

    image(image="/path/to/test.png", model="sonnet", prompt="What is in this image?")

Expected behavior

Image tool succeeds using AWS SDK credential resolution, same as chat.

Actual behavior

All image requests to Bedrock fail with:

All image models failed (2): amazon-bedrock/us.anthropic.claude-sonnet-4-6:
  No API key resolved for provider "amazon-bedrock" (auth mode: aws-sdk).
  | amazon-bedrock/us.amazon.nova-pro-v1:0:
  No API key resolved for provider "amazon-bedrock" (auth mode: aws-sdk).

Tried models: opus, sonnet, nova — all fail with the same error. Chat with the same models on the same agent works.

Root Cause:

In src/media-understanding/image.ts, resolveImageRuntime unconditionally calls requireApiKey:

// src/media-understanding/image.ts (around L197-L206)
const apiKeyInfo = await getApiKeyForModel({ model, ... });
const apiKey = requireApiKey(apiKeyInfo, model.provider);   // throws for aws-sdk
authStorage.setRuntimeApiKey(model.provider, apiKey);
return { apiKey, model };

requireApiKey (in src/agents/model-auth-runtime-shared.ts) throws whenever auth.apiKey is empty, regardless of auth.mode:

export function requireApiKey(auth: ResolvedProviderAuth, provider: string): string {
  const key = normalizeSecretInput(auth.apiKey);
  if (key) return key;
  throw new Error(`No API key resolved for provider "${provider}" (auth mode: ${auth.mode}).`);
}

The chat path (prepareSimpleCompletionModel in src/agents/simple-completion-runtime.ts) has an explicit allowMissingApiKeyModes parameter for exactly this case:

// src/agents/simple-completion-runtime.ts (around L182-L194)
if (
  !rawApiKey &&
  !hasMissingApiKeyAllowance({ mode: auth.mode, allowMissingApiKeyModes: params.allowMissingApiKeyModes })
) {
  return { error: `No API key resolved for provider "${resolved.model.provider}" (auth mode: ${auth.mode}).`, auth };
}

The image tool has no equivalent escape hatch. Same pattern affects:

  • src/media-understanding/image.ts:205resolveImageRuntime (primary image path)
  • src/media-understanding/image.ts:307resolveMinimaxVlmFallbackRuntime (MiniMax VLM fallback)
  • src/media-understanding/runner.entries.ts:407primaryApiKey: requireApiKey(auth, params.providerId) (audio/video transcription path; same bug class, will fail for Bedrock Whisper/transcription if used)

Proposed fix:

Give the media-understanding resolvers the same allowMissingApiKeyModes treatment as prepareSimpleCompletionModel, default ["aws-sdk"] when the provider is amazon-bedrock, and pass the empty apiKey through to complete() — which already resolves AWS SDK credentials at call time for Bedrock (that's why chat works).

Rough shape:

// src/media-understanding/image.ts :: resolveImageRuntime
const apiKeyInfo = await getApiKeyForModel({ model, ... });
const rawApiKey = apiKeyInfo.apiKey?.trim();
if (!rawApiKey && apiKeyInfo.mode !== "aws-sdk") {
  requireApiKey(apiKeyInfo, model.provider); // preserves existing error for non-aws-sdk
}
const apiKey = rawApiKey ?? "";
if (apiKey) authStorage.setRuntimeApiKey(model.provider, apiKey);
return { apiKey, model };

Apply the same pattern to resolveMinimaxVlmFallbackRuntime and runner.entries.ts:407.

OpenClaw version

OpenClaw 2026.4.24 (cbcfdf6)

Operating system

Ubuntu 24.04.4 LTS / aarch64 on AWS EC2

Install method

npm global

Model

amazon-bedrock/us.anthropic.claude-opus-4-7

Provider / routing chain

openclaw -> AWS Bedrock SDK default chain (IAM instance profile) -> opus 4.7

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

No response

Additional information

No response

extent analysis

TL;DR

The most likely fix is to add an allowMissingApiKeyModes parameter to the image tool's authentication flow, similar to the chat path, to handle AWS SDK credential resolution for Bedrock models.

Guidance

  • Identify the resolveImageRuntime function in src/media-understanding/image.ts and modify it to conditionally require an API key based on the authentication mode.
  • Add a default allowMissingApiKeyModes value of ["aws-sdk"] when the provider is amazon-bedrock to allow the image tool to use AWS SDK credentials.
  • Apply the same pattern to resolveMinimaxVlmFallbackRuntime and runner.entries.ts:407 to ensure consistent behavior.
  • Verify that the image tool can successfully authenticate with Bedrock models using AWS SDK credentials.

Example

// src/media-understanding/image.ts :: resolveImageRuntime
const apiKeyInfo = await getApiKeyForModel({ model, ... });
const rawApiKey = apiKeyInfo.apiKey?.trim();
if (!rawApiKey && apiKeyInfo.mode !== "aws-sdk") {
  requireApiKey(apiKeyInfo, model.provider); // preserves existing error for non-aws-sdk
}
const apiKey = rawApiKey ?? "";
if (apiKey) authStorage.setRuntimeApiKey(model.provider, apiKey);
return { apiKey, model };

Notes

This fix assumes that the AWS SDK credential resolution is correctly configured and functional for the chat path. If issues persist, verify the AWS SDK setup and credential resolution process.

Recommendation

Apply the proposed fix to add the allowMissingApiKeyModes parameter and modify the authentication flow to handle AWS SDK credentials for Bedrock models. This should resolve the authentication issue and allow the image tool to work correctly with Bedrock models.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Image tool succeeds using AWS SDK credential resolution, same as chat.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING