openclaw - ✅(Solved) Fix Discord inbound media paths are inaccessible to read tool outside workspace sandbox [1 pull requests, 1 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#59278Fetched 2026-04-08 02:26:31
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

Root Cause

Observed in a Discord-agent runtime using the read tool. When a user uploads an image in a Discord channel, the inbound media is exposed in the message envelope as an absolute path under ~/.openclaw/media/inbound/..., but read rejects it because it escapes the workspace sandbox.

PR fix notes

PR #67723: fix(agents): allow workspaceOnly inbound image loads from managed media dir

Description (problem / solution / changelog)

Note: AI-assisted (Claude Opus 4.6). Lightly tested: unit tests added (34/34 pass), pnpm build + pnpm check clean, live-verified via bundle patch against 2026.4.14 on my install. Pre-review with codex review --base upstream/main — iteration below reflects its feedback.

Summary

  • Problem: Multimodal agents with tools.fs.workspaceOnly: true cannot see inbound images on channels like WhatsApp/Telegram/Discord. The native image loader rejects paths like ~/.openclaw/media/inbound/<uuid>.jpg with Path escapes sandbox root, even though OpenClaw's own inbound pipeline wrote them. Agents then hallucinate content from the [media attached: ...] text reference.
  • Fix: skip assertSandboxPath when the target is inside path.join(getMediaDir(), "inbound"). Mirrors the existing media://inbound/<id> URI path in the same file, which already treats the inbound media dir as trusted.
  • What did NOT change: The lexical resolveSandboxPath check is untouched. workspaceOnly still blocks reads from arbitrary paths, from other media/ subdirs (outbound, tool-*, remote-cache), from other agents' workspaces, from credentials dirs, etc. Sandboxed agents (with a sandbox runtime) follow resolveSandboxedBridgeMediaPath, unchanged.

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • Skills / tool execution
  • Integrations

Linked Issue/PR

  • Closes #59278 (exact match — same error message, same code path)
  • Related #64434 (same root cause; NemoClaw shipped a broader symlink workaround downstream waiting for this fix)
  • Related #54445 (same pattern on the outbound onBlockReply path, not addressed here)
  • This PR fixes a bug or regression

Root Cause

The workspaceOnly && !sandbox branch of loadImageFromRef always enforces assertSandboxPath, whose lexical path.relative check fails for any path outside the workspace root — including OpenClaw-managed inbound media paths. The sibling media://inbound/<id> URI branch already treats the same directory as trusted; the raw-path branch was missing the equivalent check.

Regression Test Plan

Three new unit tests in src/agents/pi-embedded-runner/run/images.test.ts:

  • Positive: workspaceOnly: true + no sandbox + path inside getMediaDir()/inbound/ → image loads
  • Negative (Codex-feedback-driven): same config + path inside media/outbound/ or media/tool-image-generation/ → still rejected
  • Negative: same config + path outside both workspace and media dir → still rejected

All pass. Full images.test.ts (34 tests) passes. pnpm build + pnpm check clean.

User-visible / Behavior Changes

Multimodal agents with workspaceOnly: true can now actually see inbound images on channel-driven turns. Default-config agents unaffected. Sandboxed agents unaffected.

Security Impact (required)

  • New permissions/capabilities? No — narrow exception for the inbound-attachment subdir OpenClaw itself writes on message receipt
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? Yes, narrowly. workspaceOnly agents can now read from ~/.openclaw/media/inbound/. Other media/ subdirs (outbound, tool-*, remote-cache) and everything else remain blocked by the unchanged assertSandboxPath. Negative-control tests lock both in.

Known tradeoff (flagged by codex review, left for maintainer judgment)

codex review noted that this broadens the effective read surface beyond the existing opaque media://inbound/<id> exemption. Specifically: an absolute inbound path referenced in a past turn's transcript could be re-read in a future turn. The strictly tighter fix would be a per-turn allowlist of paths the gateway injected into the current inbound context, checked instead of a directory prefix.

I didn't implement that here because:

  1. It's a larger surgery — needs plumbing through detectAndLoadPromptImages / loadImageFromRef options
  2. This PR already moves workspaceOnly agents from hallucinating → seeing correct content, which is the user-facing fix
  3. The narrower directory-prefix bypass is still strictly safer than the current broken alternatives being shipped downstream (e.g., NemoClaw's symlink of the entire stateDir/media into the workspace per #64434)

Happy to either (a) land this as a pragmatic step and track the per-turn allowlist as a follow-up, or (b) expand this PR if maintainers prefer. Will defer to your call.

Repro

WhatsApp agent with tools.fs.workspaceOnly: true + openai-codex/gpt-5.4. Send image in DM. Before: promptImages=0, hallucinated reply, debug log shows Native image: failed to load ...: Path escapes sandbox root (~/.openclaw/workspace-<name>): .... After: verified locally by patching the installed bundle with the same logic; agent describes actual image contents correctly.

Changed files

  • src/agents/pi-embedded-runner/run/images.test.ts (modified, +92/-0)
  • src/agents/pi-embedded-runner/run/images.ts (modified, +16/-6)
RAW_BUFFERClick to expand / collapse

Observed in a Discord-agent runtime using the read tool. When a user uploads an image in a Discord channel, the inbound media is exposed in the message envelope as an absolute path under ~/.openclaw/media/inbound/..., but read rejects it because it escapes the workspace sandbox.

Symptom:

  • inbound message includes media path like /home/.../.openclaw/media/inbound/<uuid>.png
  • calling read on that path fails with: Path escapes sandbox root (~/.openclaw/workspace-discord)
  • result: the agent cannot inspect Discord-uploaded images even though the media path is present in context

Expected:

  • inbound Discord media should be readable by the agent, or
  • the runtime should expose a safe workspace-relative copy/symlink, or
  • the read tool should be allowed to access provider-managed inbound media paths

Impact:

  • breaks image understanding workflows in Discord channel sessions
  • user expectation is that uploaded pictures are available to the assistant

Notes:

  • this is distinct from sending media; the issue is inbound media access for analysis
  • current message/tool hints even encourage using message tool for image sends, but inbound inspection remains blocked by sandbox path policy

extent analysis

TL;DR

The issue can be resolved by making the inbound media path accessible within the sandbox or by providing a workspace-relative copy/symlink to the media.

Guidance

  • Verify that the ~/.openclaw/media/inbound/ directory is not already symlinked or mounted within the ~/.openclaw/workspace-discord sandbox, which could simplify access.
  • Consider modifying the Discord-agent runtime to create a workspace-relative symlink to the inbound media, allowing the read tool to access it without escaping the sandbox.
  • Investigate adjusting the sandbox path policy to explicitly allow access to the ~/.openclaw/media/inbound/ directory for the read tool, if symlinking is not feasible.
  • Review the current message/tool hints to ensure they align with the expected behavior for inbound media inspection, potentially updating them to reflect any workarounds or solutions implemented.

Example

No specific code example is provided due to the lack of detailed implementation specifics in the issue description. However, the solution might involve creating a symlink within the sandbox to the inbound media directory, such as ln -s ~/.openclaw/media/inbound/ ~/.openclaw/workspace-discord/media-inbound.

Notes

The exact implementation details may vary based on the specific requirements and constraints of the Discord-agent runtime and the read tool. It's also important to consider security implications when adjusting sandbox policies or creating symlinks to ensure that the solution does not introduce vulnerabilities.

Recommendation

Apply a workaround by creating a workspace-relative symlink to the inbound media, as this approach seems to balance the need for access with the security constraints of the sandbox environment. This method allows for the inspection of inbound media without requiring significant changes to the sandbox policy or the underlying runtime.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING