openclaw - 💡(How to fix) Fix Bug: MEDIA directive fails for agents with workspace-* directory paths (regression in 2026.5.22)

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…

Root Cause

Traced through the code to src/media/local-media-access.tsassertLocalMediaAllowed():

if (localRoots === undefined) {
  const workspaceRoot = roots.find((root) => path.basename(root) === "workspace");
  if (workspaceRoot) {
    const stateDir = path.dirname(workspaceRoot);
    const rel = path.relative(stateDir, resolved);
    if (rel && isPathInside(stateDir, resolved)) {
      const firstSegment = rel.split(path.sep)[0] ?? "";
      if (firstSegment.startsWith("workspace-")) {
        throw new LocalMediaAccessError(
          "path-not-allowed",
          `Local media path is not under an allowed directory: ${mediaPath}`
        );
      }
    }
  }
}

The guard on line 73 (firstSegment.startsWith("workspace-")) rejects any path starting with workspace-. While this guard was also present in 2026.5.4 (introduced March 23, 2026), it was never triggered because localRoots was always populated with the agent's actual workspace directory.

In 2026.5.22, something changed that causes localRoots to be undefined for non-main agent sessions during the MEDIA reply path, hitting the fallback getDefaultLocalRoots() path and triggering the rejection.

The most likely related change is #85283 (sub-agent bootstrap context change), which may have side-effected the workspaceDir / localRoots resolution during reply delivery.

Fix Action

Workaround

Using feishu_send.py (direct Feishu API file upload) works correctly — the Feishu bot's im:file permissions are intact. The issue is specifically in OpenClaw's MEDIA directive path resolution.

Code Example

agent main → workspace: ~/.openclaw/workspace
   agent xiaoqian → workspace: ~/.openclaw/workspace-xiaoqian

---

if (localRoots === undefined) {
  const workspaceRoot = roots.find((root) => path.basename(root) === "workspace");
  if (workspaceRoot) {
    const stateDir = path.dirname(workspaceRoot);
    const rel = path.relative(stateDir, resolved);
    if (rel && isPathInside(stateDir, resolved)) {
      const firstSegment = rel.split(path.sep)[0] ?? "";
      if (firstSegment.startsWith("workspace-")) {
        throw new LocalMediaAccessError(
          "path-not-allowed",
          `Local media path is not under an allowed directory: ${mediaPath}`
        );
      }
    }
  }
}
RAW_BUFFERClick to expand / collapse

Bug Description

After upgrading from 2026.5.4 to 2026.5.22, the MEDIA: directive fails for agents with workspace directories named workspace-* (e.g. workspace-xiaoqian). The reply is delivered with ⚠️ Media failed. appended, and the file is not sent to the chat channel.

Main agent (workspace workspace, no suffix) works fine. All other configured agents with namespaced workspace directories fail.

Steps to Reproduce

  1. Configure multiple agents with separate workspace directories:
    agent main → workspace: ~/.openclaw/workspace
    agent xiaoqian → workspace: ~/.openclaw/workspace-xiaoqian
  2. Have the sub-agent write a file in its workspace, then reply with MEDIA:/path/to/workspace-xiaoqian/file.html
  3. On 2026.5.4: file is delivered ✅
  4. On 2026.5.22: ⚠️ Media failed.

Root Cause Analysis

Traced through the code to src/media/local-media-access.tsassertLocalMediaAllowed():

if (localRoots === undefined) {
  const workspaceRoot = roots.find((root) => path.basename(root) === "workspace");
  if (workspaceRoot) {
    const stateDir = path.dirname(workspaceRoot);
    const rel = path.relative(stateDir, resolved);
    if (rel && isPathInside(stateDir, resolved)) {
      const firstSegment = rel.split(path.sep)[0] ?? "";
      if (firstSegment.startsWith("workspace-")) {
        throw new LocalMediaAccessError(
          "path-not-allowed",
          `Local media path is not under an allowed directory: ${mediaPath}`
        );
      }
    }
  }
}

The guard on line 73 (firstSegment.startsWith("workspace-")) rejects any path starting with workspace-. While this guard was also present in 2026.5.4 (introduced March 23, 2026), it was never triggered because localRoots was always populated with the agent's actual workspace directory.

In 2026.5.22, something changed that causes localRoots to be undefined for non-main agent sessions during the MEDIA reply path, hitting the fallback getDefaultLocalRoots() path and triggering the rejection.

The most likely related change is #85283 (sub-agent bootstrap context change), which may have side-effected the workspaceDir / localRoots resolution during reply delivery.

Environment

  • OS: Ubuntu 22.04 (Linux 6.8.0)
  • Node: v22.22.2
  • Channel: Feishu (WebSocket mode)
  • Config: multiple agents with separate workspace dirs

Workaround

Using feishu_send.py (direct Feishu API file upload) works correctly — the Feishu bot's im:file permissions are intact. The issue is specifically in OpenClaw's MEDIA directive path resolution.

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