openclaw - ✅(Solved) Fix exec 工具不支持 `~` 路径解析,与 read 工具行为不一致 [2 pull requests, 2 comments, 2 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#63742Fetched 2026-04-10 03:41:58
View on GitHub
Comments
2
Participants
2
Timeline
8
Reactions
0
Timeline (top)
referenced ×4commented ×2cross-referenced ×2

Error Message

  • 期望行为:返回 Error,停止执行,要求用户提供有效路径

修复2:无效 workdir 应返回 Error 而非 Warning 回退

"error": f"workdir does not exist: {workdir}",

Fix Action

Fixed

PR fix notes

PR #63778: fix: exec tool workdir should expand ~ and throw on invalid path

Description (problem / solution / changelog)

This PR fixes issue #63742 where the exec tool's workdir parameter did not expand ~ to the home directory (unlike the read tool), and would silently fall back to the home directory when the workdir was invalid instead of throwing an error.

Changes

src/agents/bash-tools.shared.ts

  • Modified resolveWorkdir to expand ~ using path.join(os.homedir(), workdir.slice(1))
  • Changed behavior to throw an error when workdir is invalid instead of silently falling back

src/agents/bash-tools.exec.ts

  • Updated the call to resolveWorkdir to use the new signature

src/agents/bash-tools.shared.test.ts

  • Added tests for resolveWorkdir covering ~ expansion and error cases

fix #63742

Changed files

  • src/agents/bash-tools.exec.ts (modified, +1/-1)
  • src/agents/bash-tools.shared.test.ts (modified, +37/-2)
  • src/agents/bash-tools.shared.ts (modified, +14/-21)

PR #63806: fix(exec): expand ~ in workdir and error on invalid path

Description (problem / solution / changelog)

What does this PR do?

The exec tool did not expand ~ in workdir paths before resolving them. Node.js does not expand ~ like the shell does, so workdir="~/projects" silently fell back to the home directory instead of running in the intended path. This PR fixes that and also changes the silent fallback to a hard error so callers know when a workdir is invalid.

Root Cause

resolveWorkdir in src/agents/bash-tools.shared.ts called statSync on the raw workdir string. The read tool already handles this correctly via expandHomePrefix in fs-safe.tsresolveWorkdir was written independently without that step. No tests existed for resolveWorkdir with ~-prefixed paths, so the silent fallback went undetected.

Changes

  • resolveWorkdir now calls expandHomePrefix before statSync, consistent with the read tool.
  • When the workdir does not exist, the function throws a hard error instead of silently falling back to home. If tilde was expanded, the resolved path is included in the error message.
  • 5 new unit tests added to src/agents/bash-tools.shared.test.ts covering: valid absolute path, ~ expansion, ~/subpath expansion, missing absolute path, missing ~/... path.
  • One-line CHANGELOG entry added under ## Unreleased → ### Fixes.
  • No changes to resolveSandboxWorkdir or any other call sites.

Expected Impact

  • exec workdir="~/..." paths now resolve to the correct directory.
  • Passing a non-existent workdir now surfaces an error to the caller instead of running silently in the home directory.
  • All existing behavior for valid absolute paths is unchanged.

Type of Change

  • Bug fix

Checklist

  • Tests added / updated (src/agents/bash-tools.shared.test.ts — 5 new tests, all 8 pass)
  • All tests pass (pnpm test — 35/35)
  • CHANGELOG updated
  • No unrelated files modified
  • Backward compatible — callers with valid paths see identical behavior

Closes #63742

Changed files

  • CHANGELOG.md (modified, +1/-10)
  • src/agents/bash-tools.shared.test.ts (modified, +50/-2)
  • src/agents/bash-tools.shared.ts (modified, +14/-19)

Code Example

read path="~/.openclaw/workspace/skills/mcdonald-mcp/SKILL.md"

---

exec command="python scripts/mcp_client.py init_order" workdir="~/.openclaw/workspace/skills/mcdonald-mcp"

---

Warning: workdir "~/.openclaw/workspace/skills/mcdonald-mcp" is unavailable; using "/home/xjc".

python: can't open file '/home/xjc/scripts/mcp_client.py': [Errno 2] No such file or directory

(Command exited with code 2)

---

import os

def exec_command(command, workdir=None, timeout=30):
    # 扩展 ~ 路径
    if workdir:
        workdir = os.path.expanduser(workdir)
    
    # 继续执行命令...

---

if workdir and not os.path.isdir(workdir):
    return {
        "error": f"workdir does not exist: {workdir}",
        "suggestion": "Please provide a valid absolute path"
    }

---

{"type":"message","id":"1568fe14","parentId":"ac3c80bd","timestamp":"2026-04-09T12:06:09.751Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_fv6eyezsnw3nd19s3wvy58w6","name":"exec","arguments":{"command":"python scripts/mcp_client.py init_order","workdir":"~/.openclaw/workspace/skills/mcdonald-mcp","timeout":30}}]}}

{"type":"message","id":"ffed4b5b","parentId":"1568fe14","timestamp":"2026-04-09T12:06:09.861Z","message":{"role":"toolResult","toolCallId":"call_fv6eyezsnw3nd19s3wvy58w6","toolName":"exec","content":[{"type":"text","text":"Warning: workdir \"~/.openclaw/workspace/skills/mcdonald-mcp\" is unavailable; using \"/home/xjc\".\n\npython: can't open file '/home/xjc/scripts/mcp_client.py': [Errno 2] No such file or directory\n\n(Command exited with code 2)"}],"details":{"status":"completed","exitCode":2,"durationMs":40,"cwd":"/home/xjc"}}}

---

{"type":"message","id":"29826e2c","parentId":"bbcffdea","timestamp":"2026-04-09T12:06:01.118Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_vqufc8nppw8d3mx8wrw0d5fb","name":"read","arguments":{"path":"~/.openclaw/workspace/skills/mcdonald-mcp/SKILL.md"}}]}}

{"type":"message","id":"ac3c80bd","parentId":"29826e2c","timestamp":"2026-04-09T12:06:01.222Z","message":{"role":"toolResult","toolCallId":"call_vqufc8nppw8d3mx8wrw0d5fb","toolName":"read","content":[{"type":"text","text":"---\nname: mcdonald-mcp\ndescription: \"McDonald's China MCP integration..."}]}}
RAW_BUFFERClick to expand / collapse

Issue: exec 工具不支持 ~ 路径解析,与 read 工具行为不一致

问题概述

openclaw 系统内部工具对 ~ 路径的支持不一致:

  • read 工具:✅ 支持 ~ 路径
  • exec 工具:❌ 不支持 ~ 路径

此外,exec 工具在收到无效 workdir 时隐式回退到主目录而非报错,可能导致命令在错误目录执行。

复现步骤

  1. AI 读取技能文件时使用 ~ 路径:

    read path="~/.openclaw/workspace/skills/mcdonald-mcp/SKILL.md"

    结果:✅ 成功读取

  2. AI 使用相同的 ~ 路径作为 exec 的 workdir:

    exec command="python scripts/mcp_client.py init_order" workdir="~/.openclaw/workspace/skills/mcdonald-mcp"

    结果:❌ 失败,隐式回退到 /home/xjc

错误信息

Warning: workdir "~/.openclaw/workspace/skills/mcdonald-mcp" is unavailable; using "/home/xjc".

python: can't open file '/home/xjc/scripts/mcp_client.py': [Errno 2] No such file or directory

(Command exited with code 2)

问题分析

问题1:工具行为不一致

工具路径参数~ 路径支持结果
readpath: ~/.openclaw/...✅ 支持成功
execworkdir: ~/.openclaw/...❌ 不支持失败

同一系统内的工具对相同格式的路径处理不一致,会导致 AI 困惑。

问题2:隐式回退行为危险

exec 工具收到无法解析的 workdir 时:

  • 当前行为:返回 Warning,隐式回退到主目录,继续执行命令
  • 期望行为:返回 Error,停止执行,要求用户提供有效路径

隐式回退的危害

  • 命令可能在错误目录执行
  • 可能产生意外后果(如删除错误目录的文件)
  • AI 可能忽略 Warning 信息

建议修复

修复1:统一工具对 ~ 路径的支持

exec 工具中添加路径扩展逻辑(参考 read 工具的实现):

import os

def exec_command(command, workdir=None, timeout=30):
    # 扩展 ~ 路径
    if workdir:
        workdir = os.path.expanduser(workdir)
    
    # 继续执行命令...

修复2:无效 workdir 应返回 Error 而非 Warning 回退

if workdir and not os.path.isdir(workdir):
    return {
        "error": f"workdir does not exist: {workdir}",
        "suggestion": "Please provide a valid absolute path"
    }

影响范围

  • 所有使用技能路径的 exec 调用都会遇到此问题
  • openclaw 系统给 AI 提供的技能路径格式为 ~/.openclaw/workspace/skills/xxx/SKILL.md
  • AI 需要手动转换路径,增加认知负担
  • 新用户容易遇到此问题

环境信息

  • openclaw 版本:(请补充)
  • 操作系统:Linux
  • 会话 ID:12c3b839-1aa1-4900-acb3-99ecaddb72c5

相关日志

原始会话日志:~/.openclaw/agents/main/sessions/12c3b839-1aa1-4900-acb3-99ecaddb72c5.jsonl

关键日志片段(exec 工具调用失败):

{"type":"message","id":"1568fe14","parentId":"ac3c80bd","timestamp":"2026-04-09T12:06:09.751Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_fv6eyezsnw3nd19s3wvy58w6","name":"exec","arguments":{"command":"python scripts/mcp_client.py init_order","workdir":"~/.openclaw/workspace/skills/mcdonald-mcp","timeout":30}}]}}

{"type":"message","id":"ffed4b5b","parentId":"1568fe14","timestamp":"2026-04-09T12:06:09.861Z","message":{"role":"toolResult","toolCallId":"call_fv6eyezsnw3nd19s3wvy58w6","toolName":"exec","content":[{"type":"text","text":"Warning: workdir \"~/.openclaw/workspace/skills/mcdonald-mcp\" is unavailable; using \"/home/xjc\".\n\npython: can't open file '/home/xjc/scripts/mcp_client.py': [Errno 2] No such file or directory\n\n(Command exited with code 2)"}],"details":{"status":"completed","exitCode":2,"durationMs":40,"cwd":"/home/xjc"}}}

对比日志(read 工具调用成功,使用相同的 ~ 路径格式):

{"type":"message","id":"29826e2c","parentId":"bbcffdea","timestamp":"2026-04-09T12:06:01.118Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_vqufc8nppw8d3mx8wrw0d5fb","name":"read","arguments":{"path":"~/.openclaw/workspace/skills/mcdonald-mcp/SKILL.md"}}]}}

{"type":"message","id":"ac3c80bd","parentId":"29826e2c","timestamp":"2026-04-09T12:06:01.222Z","message":{"role":"toolResult","toolCallId":"call_vqufc8nppw8d3mx8wrw0d5fb","toolName":"read","content":[{"type":"text","text":"---\nname: mcdonald-mcp\ndescription: \"McDonald's China MCP integration..."}]}}

extent analysis

TL;DR

  • Update the exec tool to support ~ pathway resolution and return an error for invalid workdirs instead of falling back to the home directory.

Guidance

  • Modify the exec tool to use os.path.expanduser() for pathway expansion, ensuring consistent behavior with the read tool.
  • Implement error handling in the exec tool to return an error when an invalid workdir is provided, rather than falling back to the home directory.
  • Review and update all exec calls that use ~ pathways to ensure they are correctly resolved.
  • Consider adding logging or monitoring to detect and report instances where the exec tool falls back to the home directory due to an invalid workdir.

Example

import os

def exec_command(command, workdir=None, timeout=30):
    # Expand ~ pathways
    if workdir:
        workdir = os.path.expanduser(workdir)
    
    # Check if workdir is valid
    if workdir and not os.path.isdir(workdir):
        return {
            "error": f"workdir does not exist: {workdir}",
            "suggestion": "Please provide a valid absolute path"
        }
    
    # Continue executing the command...

Notes

  • The provided solution assumes that the exec tool is implemented in Python and has access to the os module.
  • The os.path.expanduser() function is used to expand ~ pathways, which may not work as expected in all environments or operating systems.
  • Additional error handling and logging may be necessary to ensure the exec tool behaves correctly in all scenarios.

Recommendation

  • Apply the workaround by updating the exec tool to support ~ pathway resolution and return an error for invalid workdirs.
  • This approach ensures consistent behavior with the read tool and prevents potential issues caused by falling back to the home directory.

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