#Problem/Bug with imageModel with Anthropic API Key (SecretRef) returns 401

1 messages · Page 1 of 1 (latest)

upper yoke
#

Hey community! I've been struggling with an imageModel issue and just filed GitHub Issue #69620.

The problem:
My primary model is ollama/glm-5:cloud — no vision capability. So I configured agents.defaults.imageModel.primary: anthropic/claude-haiku-4-5. The Anthropic API key is correctly set up via SecretRef (env:ANTHROPIC_API_KEY) in auth-profiles.json.
openclaw models status shows:
anthropic:default=ref(env:ANTHROPIC_API_KEY)
Direct curl with the same key works (HTTP 200 )
But when sending an image:
401 {"type":"authentication_error","message":"invalid x-api-key"}

Setup:
OpenClaw 2026.4.15
Ubuntu 24.04, npm global
Auth via API key (sk-ant-api03-...), no OAuth/oat01 token
models auth order explicitly set to anthropic:default
profile field in imageModel config rejected by schema

Looks like the imageModel doesn't correctly inherit the auth profile from the anthropic provider config. Has anyone seen this or found a workaround?

GitHub Issue: https://github.com/openclaw/openclaw/issues/69620

Tnx
Madelaine

nimble pastureBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

weak mauveBOT
rare drumBOT
#

I’m checking one more angle before I answer, because the exact error shape matters here: a 401 invalid x-api-key usually means OpenClaw did send some Anthropic key, just not the one you expect. That’s a bit different from “profile not loaded at all.”

#

I dug through the code a bit, and this looks real, but I don’t think the bug is exactly “imageModel ignores auth-profiles.json`”.

What the image path does now is basically:

resolveImageModelConfigForTool → describeImageWithModel → getApiKeyForModel → resolveApiKeyForProvider

So in theory it should honor auth.order and pick anthropic:default.

What is true:

  • agents.defaults.imageModel only accepts string or { primary, fallbacks }
  • it does not support profile
  • tools.media.image.models[] does support profile / preferredProfile

My best guess for the 401 is this:

  • the Anthropic profile resolution is failing in that image path for some reason
#
  • then auth falls through to env auth
  • for Anthropic, env fallback prefers ANTHROPIC_OAUTH_TOKEN before ANTHROPIC_API_KEY

So if the gateway/service env has a stale ANTHROPIC_OAUTH_TOKEN, you get exactly this kind of invalid x-api-key mess.

Best workarounds right now

  1. Check the gateway env, not just your shell
    openclaw models status showing ref(env:ANTHROPIC_API_KEY) does not prove the running gateway actually used that value.

  2. Force provider-level Anthropic auth
    This is the strongest workaround for imageModel right now:

{
  models: {
#
    providers: {
      anthropic: {
        auth: "api-key",
        apiKey: { source: "env", provider: "default", id: "ANTHROPIC_API_KEY" }
      }
    }
  },
  agents: {
    defaults: {
      model: { primary: "ollama/glm-5:cloud" },
      imageModel: { primary: "anthropic/claude-haiku-4-5" }
    }
  }
}
#
  1. If your goal is inbound image understanding, use tools.media.image.models instead
    That path lets you pin the profile explicitly:
{
  tools: {
    media: {
      image: {
        models: [
          {
            provider: "anthropic",
            model: "claude-haiku-4-5",
            profile: "anthropic:default"
          }
        ]
      }
upper yoke
#

Additional finding:
The error is not just about auth. There's a second issue in the same image path:
Local media path is not under an allowed directory:
/home/m-agents/.openclaw/media/inbound/<uuid>.jpg
This happens even with tools.fs.workspaceOnly: false set.
Setup:

Signal inbound image → stored at /home/m-agents/.openclaw/media/inbound/
tools.media.image.models configured with anthropic/claude-haiku-4-5 + profile: "anthropic:default"
Gateway restarted after each config change

Two separate failures:

Auth: 401 invalid x-api-key (original issue)
Path: Local media path is not under an allowed directory — media/inbound/ appears not to be in the allowed roots for the image tool path, despite being an OpenClaw-managed directory

Per docs, media/inbound/ should be within the allowed media cache paths. Looks like either the path check is broken or media/inbound/ is not registered as an allowed root in 4.15.

rare drumBOT
#

I’m going to check the media-root bit too, because that one sounds like a separate regression and the exact path handling matters.

#

Yep, that does look like a second bug, and I think the two may actually share the same root cause.

A couple important details from the code:

  • tools.fs.workspaceOnly: false is not “allow any host path” for the image tool.
  • The image tool still only allows:
    • the workspace
    • OpenClaw media/cache roots
  • tests explicitly reject random non-workspace image paths even when workspaceOnly is off

So your expectation is right in one narrow sense:

  • /home/m-agents/.openclaw/media/inbound/<uuid>.jpg should be allowed
  • but only if the running gateway believes its state dir is /home/m-agents/.openclaw

That is why I’m suspicious these two failures are related:

#
  1. Auth falls back to the wrong env/runtime creds
  2. Path check computes allowed media roots from a different HOME / OPENCLAW_STATE_DIR

If the service is running with a different env than your shell, both happen at once.

My read

  • If the gateway’s real state dir is not /home/m-agents/.openclaw, the path error is expected.
  • If the gateway’s real state dir is /home/m-agents/.openclaw and it still rejects media/inbound, then yes, I’d call that a legit 4.15 bug.

What I’d verify next

Check the running gateway env/path context, not the interactive shell:

  • HOME
  • OPENCLAW_STATE_DIR
  • config path / active state dir the daemon is actually using
#

Because right now, “shell curl works” + “gateway image path/auth both fail” really smells like daemon env mismatch.

Also, if you are sandboxing the agent, the safe form is usually the rewritten sandbox path, like:

  • media/inbound/<file>
  • not the host absolute path

So I’d summarize it as:

  • Auth issue: still looks real
  • Path issue: also looks real, unless the gateway is simply using a different state dir than the one in the pasted path

If you want, I can help you write one clean follow-up on #69620 that frames this as:

  1. probable daemon env/state-dir mismatch vector, and
  2. possible separate media/inbound allow-root bug in 2026.4.15.
upper yoke
#

Checked the running gateway process env directly via /proc/<pid>/environ:

HOME=/home/m-agents âś…
OPENCLAW_STATE_DIR: not set (derived from HOME → /home/m-agents/.openclaw) ✅
ANTHROPIC_API_KEY: present and correct in daemon env âś…

No env/state-dir mismatch. Both failures appear to be genuine 4.15 bugs:

  1. Auth: gateway has the correct key but image path sends wrong credentials
  2. Path: /home/m-agents/.openclaw/media/inbound/ rejected despite being
    under the correct state dir
rare drumBOT
#

Nice, that’s a really useful check.

If /proc/<pid>/environ confirms:

  • HOME=/home/m-agents
  • no OPENCLAW_STATE_DIR override
  • correct ANTHROPIC_API_KEY in the daemon env

then yeah, I agree, this now looks like two genuine 2026.4.15 bugs.

Why I think that:

  • the default media roots are derived from resolveStateDir()
  • those roots include stateDir/media
  • so /home/m-agents/.openclaw/media/inbound/... should be allowed

and

#
  • the image auth path is supposed to go through normal provider auth resolution
  • so with the correct daemon env + anthropic:default, it should not be sending a bad key

One tiny last thing I’d still sanity-check is whether ANTHROPIC_OAUTH_TOKEN is also present in that same daemon env, because Anthropic env lookup prefers that over ANTHROPIC_API_KEY. If it’s absent too, then I’d call the auth side fully confirmed-bug, not config.

At this point I’d add exactly this to #69620:

  1. daemon env matches expected HOME/state dir
  2. correct ANTHROPIC_API_KEY is present in the running gateway
  3. /home/m-agents/.openclaw/media/inbound/... is still rejected
  4. therefore both auth and allowed-root handling are broken in the image path on 4.15

That’s strong evidence, not guesswork anymore.

upper yoke
#

After updating to 2026.4.21: Auth issue appears fixed (no more 401). Path issue persists: Local media path is not under an allowed directory: /home/agents/.openclaw/media/inbound/<uuid>.jpg — the media/inbound path is still not registered as an allowed root.

rare drumBOT
#

That’s actually good news, it means the auth bug was fixed upstream. 🎉

What’s left now looks like a separate path-root bug:

  • 2026.4.21 fixed the 401 invalid x-api-key
  • but ~/.openclaw/media/inbound/... is still being rejected as not allowed
  • so the remaining problem is specifically allowed-root registration / inbound media path handling

I’d update #69620 with exactly that split:

  • fixed in 2026.4.21: Anthropic auth for imageModel
  • still broken in 2026.4.21: Local media path is not under an allowed directory for ~/.openclaw/media/inbound/...

If they treat the auth issue as resolved, I’d then file a new dedicated issue just for the inbound media root bug, because that’s much cleaner to track.

For now, the only workaround I’d trust is:

#
  • stage/copy the image into the agent workspace and use that path, or
  • run sandboxed, where paths get rewritten to relative media/inbound/...

So yeah, this looks narrowed down nicely now: auth fixed, path bug still real.

upper yoke
#

Shall I close Issue #69620 in GitHub and open a new one with the updated info? Or is there one already opened?

rare drumBOT
#

I’ll quickly check whether there’s already a separate issue for the remaining inbound-media-root bug, so I don’t make you duplicate work.

#

I’d open a new issue for the remaining path bug, and link it from #69620.

I did a quick search and I didn’t find an exact existing issue for:

  • ~/.openclaw/media/inbound/...
  • being rejected by the image/media path allowlist
  • after auth was fixed in 2026.4.21

I found only related issues, not the same one:

So my recommendation:

#
  1. Comment on #69620: auth is fixed in 2026.4.21
  2. Open a new focused issue for the remaining media/inbound allowed-root bug
  3. Link both issues to each other
  4. Then close #69620 if you want it to stay about the auth bug only

That keeps tracking much cleaner.

upper yoke
#

Tnx

rare drumBOT
#

Glad that helped! 🎉

If this fixed the tracking plan, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it for the next person.

upper yoke
#

Bug not fully fixed in 2026.4.22 (00bd2cf) — inconsistent behavior observed:

After gateway restart:

  • First inbound image: âś… works correctly via media://inbound/
  • Subsequent images (same path structure): ❌ intermittent "Local media path
    is not under an allowed directory"
  • Multiple images sent simultaneously: mixed results (first processes,
    second fails)

Same path format: ~/.openclaw/media/inbound/<uuid>.jpg
Channel: Signal
OS: Ubuntu 24.04, npm global

Looks like a state/cache issue — the allowed-root check passes initially,
then fails for subsequent calls within the same gateway session.

Workaround: gateway restart temporarily resolves the issue.

rare drumBOT
#

Quickly tracing the remaining path check, I’m looking at the attachment cache and root-merging code now. The “first works, later fail” pattern really does smell like a stale root/path decision rather than bad media itself.

#

I dug a bit deeper, and I’m pretty convinced the remaining 2026.4.22 (00bd2cf) problem is a second bug in inbound media replay/path handling, not Anthropic auth anymore.

What I found:

  • Fresh media://inbound/<id> loads use a special path

    • src/agents/pi-embedded-runner/run/images.ts
    • it resolves the claim-check URI, then calls loadWebMedia(..., { localRoots: [getMediaDir()] })
    • that explains why the first inbound image works
  • Persisted/replayed attachments are stored as absolute MediaPath values

    • src/gateway/server-methods/chat.ts
    • offloaded media gets persisted as MediaPath / MediaPaths
    • not as MediaUrl / media://inbound/...
  • Those absolute paths then hit the generic local-path gate

    • src/media/local-media-access.ts
    • that is exactly where Local media path is not under an allowed directory is thrown
#
  • I don’t think this is attachments.cache.ts leaking across the whole gateway session
    • createMediaAttachmentCache() makes a fresh cache per apply/request

So the pattern you saw makes sense:

  • first turn = fresh media://inbound/... path, works
  • later turn/history/replay = absolute ~/.openclaw/media/inbound/<uuid>.jpg, sometimes fails in the generic allowlist path

So yeah, I’d treat this as:

  1. Auth bug: fixed upstream after 2026.4.21
  2. Remaining bug: inbound media replay/history path handling still broken/intermittent

If you update #69620, I’d add this exact note:

fresh media://inbound/<id> works, but replayed/persisted offloaded media is stored as absolute MediaPath and later hits Local media path is not under an allowed directory

upper yoke
#

yes pls 👍

rare drumBOT
#

Yep, here’s a maintainer-ready comment you can drop into #69620:

Update: the original Anthropic auth problem appears fixed in newer builds, but there is still a separate inbound-media bug in 2026.4.22 (00bd2cf).

What is fixed
- The earlier 401 `{"type":"authentication_error","message":"invalid x-api-key"}` for `agents.defaults.imageModel.primary: anthropic/claude-haiku-4-5` no longer seems to be the main issue after 2026.4.21.

What is still broken
- Inbound images are still inconsistent after gateway restart:
  - first inbound image works
  - later inbound images intermittently fail with:
    `Local media path is not under an allowed directory`
  - multiple simultaneous images can produce mixed results

Observed environment
#
- OpenClaw 2026.4.22 (00bd2cf)
- Ubuntu 24.04
- npm global install
- Channel: Signal

Observed pattern
- Fresh inbound media via `media://inbound/<id>` works
- Later/replayed handling of the same kind of attachment can fail when the path is treated as a local absolute path such as:
  `~/.openclaw/media/inbound/<uuid>.jpg`

Code-path suspicion
- Fresh `media://inbound/<id>` handling appears to go through the special inbound-media path
- Persisted/replayed attachments appear to later go through the generic local-path allowlist path
- That would explain why the first image after restart works, but later ones can fail with:
  `Local media path is not under an allowed directory`
#

Relevant files I traced locally
- `src/agents/pi-embedded-runner/run/images.ts`
- `src/gateway/server-methods/chat.ts`
- `src/media/local-media-access.ts`

So I think this issue is now split into:
1. fixed auth issue
2. still-open inbound media replay/path-allowlist issue

Workaround for now
- restarting the gateway temporarily restores the first successful inbound image

If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it for the next person.

upper yoke
#

So I reopen #69620 and leave #70277 closed, correct?

rare drumBOT
#

Actually, I’d do the opposite.

  • #69620 = original Anthropic 401 invalid x-api-key auth bug

    • if that no longer reproduces on current builds, I would leave that closed (or at most add a comment saying the auth part seems fixed)
  • #70277 = remaining Signal inbound media path / allowed-root bug

    • since that is still reproducing in 2026.4.22 (00bd2cf), I would reopen #70277 instead of reopening #69620

Reason: it keeps the tracker clean:

  • one issue for the fixed auth bug
  • one issue for the still-broken inbound media path bug

If you want, I can help you word the exact “reopen #70277” comment too.

upper yoke
#

I can't reopen the issue..."you do not have permissions to reopen this issue"

rare drumBOT
#

Yep, that’s just a GitHub permissions thing.

Best path now:

  1. Leave a comment on #70277 with the new repro

    • still reproducible on 2026.4.22 (00bd2cf)
    • first inbound image works after restart
    • later ones intermittently fail with Local media path is not under an allowed directory
    • Signal, Ubuntu 24.04, npm global
    • workaround: restart gateway
  2. Ask a maintainer in the comment to reopen it

    • something like:
      Still reproducible in 2026.4.22 (00bd2cf). I can’t reopen issues from my account, but this appears unresolved. Could a maintainer please reopen #70277?
  3. If GitHub won’t let you comment there either, open a new issue and link both:

    • #69620 for the old auth bug
#
  • #70277 for the path bug

I would not reopen #69620 for this, since the remaining bug is the path/root one, not the old 401.

If you want, I can draft the exact short comment for #70277.

upper yoke
#

Done

rare drumBOT
#

Perfect, that was the right move. 👍

Now it’s tracked in the right bucket:

  • #69620 = old auth bug
  • #70277 = still-open inbound media path bug

If a maintainer replies and wants a tighter repro, the key bit is:

  • 2026.4.22 (00bd2cf)
  • after gateway restart, first inbound image works
  • later ones intermittently fail with
    Local media path is not under an allowed directory
  • Signal, Ubuntu 24.04, npm global

Glad we untangled that one.