openclaw - 💡(How to fix) Fix gateway launchd plist missing WorkingDirectory → ENOENT on every agent turn (relative agentDir resolves under cwd=/) [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#70223Fetched 2026-04-23 07:27:33
View on GitHub
Comments
2
Participants
3
Timeline
2
Reactions
0
Author
Timeline (top)
commented ×2

The ai.openclaw.gateway.plist rendered by openclaw service install (and re-rendered by openclaw update) does not include a <key>WorkingDirectory</key>. launchd therefore starts the gateway with cwd=/.

Combined with the default ~/.openclaw/openclaw.json — which ships with a relative "agentDir": "./agents/main" — every agent turn crashes because the path resolves to /agents/main:

ENOENT: no such file or directory, mkdir '/agents/main'

Users see this in the UI as:

⚠️ Something went wrong while processing your request. Please try again, or use /new to start a fresh session.

Error Message

[AgentStore] failed to ensure agentDir: Error: ENOENT: no such file or directory, mkdir '/agents/main'

Root Cause

Two interacting defaults collide:

  • openclaw.json default uses a relative agentDir (./agents/main), which is resolved relative to process.cwd().
  • The launchd plist renderer does not set WorkingDirectory, and launchd defaults cwd to / when the key is absent.

Either one alone would be fine. Together, every agent turn explodes.

Fix Action

Workaround

For anyone hitting this right now, insert the key manually and reload:

plutil -insert WorkingDirectory -string \"$HOME\" ~/Library/LaunchAgents/ai.openclaw.gateway.plist
launchctl bootout gui/$(id -u)/ai.openclaw.gateway 2>/dev/null || true
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist

Note that `openclaw update` re-renders the plist and therefore re-introduces the bug — the workaround has to be re-applied after every update until this is fixed upstream.

Code Example

ENOENT: no such file or directory, mkdir '/agents/main'

---

plutil -extract WorkingDirectory raw ~/Library/LaunchAgents/ai.openclaw.gateway.plist
   # → Could not extract key "WorkingDirectory" from "..."

---

grep agentDir ~/.openclaw/openclaw.json
   # → "agentDir": "./agents/main",

---

lsof -a -p "$(launchctl print gui/$(id -u)/ai.openclaw.gateway | awk '/pid =/ {print $3}')" -d cwd
   # → cwd DIR ... /

---

[AgentStore] failed to ensure agentDir: Error: ENOENT: no such file or directory, mkdir '/agents/main'

---

<key>WorkingDirectory</key>
<string>$HOME</string>

---

plutil -insert WorkingDirectory -string \"$HOME\" ~/Library/LaunchAgents/ai.openclaw.gateway.plist
launchctl bootout gui/$(id -u)/ai.openclaw.gateway 2>/dev/null || true
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist
RAW_BUFFERClick to expand / collapse

Summary

The ai.openclaw.gateway.plist rendered by openclaw service install (and re-rendered by openclaw update) does not include a <key>WorkingDirectory</key>. launchd therefore starts the gateway with cwd=/.

Combined with the default ~/.openclaw/openclaw.json — which ships with a relative "agentDir": "./agents/main" — every agent turn crashes because the path resolves to /agents/main:

ENOENT: no such file or directory, mkdir '/agents/main'

Users see this in the UI as:

⚠️ Something went wrong while processing your request. Please try again, or use /new to start a fresh session.

Environment

  • openclaw 2026.4.21 (f788c88)
  • macOS 26.4 (25E246)
  • Installed via openclaw service install (launchd user agent)

Reproduction

  1. Fresh install on macOS: npm i -g openclaw && openclaw service install
  2. Confirm the rendered plist has no WorkingDirectory:
    plutil -extract WorkingDirectory raw ~/Library/LaunchAgents/ai.openclaw.gateway.plist
    # → Could not extract key "WorkingDirectory" from "..."
  3. Confirm the default config uses a relative agentDir:
    grep agentDir ~/.openclaw/openclaw.json
    # → "agentDir": "./agents/main",
  4. Confirm the daemon is running with cwd=/:
    lsof -a -p "$(launchctl print gui/$(id -u)/ai.openclaw.gateway | awk '/pid =/ {print $3}')" -d cwd
    # → cwd DIR ... /
  5. Send any prompt from a client → the gateway logs:
    [AgentStore] failed to ensure agentDir: Error: ENOENT: no such file or directory, mkdir '/agents/main'

Root cause

Two interacting defaults collide:

  • openclaw.json default uses a relative agentDir (./agents/main), which is resolved relative to process.cwd().
  • The launchd plist renderer does not set WorkingDirectory, and launchd defaults cwd to / when the key is absent.

Either one alone would be fine. Together, every agent turn explodes.

Proposed fixes (pick one)

Option A — render WorkingDirectory in the gateway plist template (smallest change, matches how most launchd agents are written):

<key>WorkingDirectory</key>
<string>$HOME</string>

…where $HOME is resolved at install time (launchd does not expand $HOME in plist strings).

Option B — resolve agentDir to an absolute path when reading openclaw.json (more defensive; also fixes the same class of bug for systemd / Windows Task Scheduler if they ever land with cwd=/).

Anchor relative agentDir (and any other relative path keys) to the directory of the loaded openclaw.json — i.e. ~/.openclaw/ — rather than process.cwd().

Option A + B together would be belt-and-braces. Personally I'd take B because it is robust against any future service manager that launches with an unhelpful cwd.

Workaround

For anyone hitting this right now, insert the key manually and reload:

plutil -insert WorkingDirectory -string \"$HOME\" ~/Library/LaunchAgents/ai.openclaw.gateway.plist
launchctl bootout gui/$(id -u)/ai.openclaw.gateway 2>/dev/null || true
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist

Note that `openclaw update` re-renders the plist and therefore re-introduces the bug — the workaround has to be re-applied after every update until this is fixed upstream.

Context

Found while maintaining an MCP bridge that exercises agent turns on every run (openclaw-local-bridge-macos). Discovered after `openclaw update` from 2026.4.15 → 2026.4.21 restarted the gateway under launchd and every subsequent agent turn began failing with the ENOENT above. 2026.4.15 was affected by the same bug but happened to be running from a shell (cwd=$HOME), which masked it.

Happy to send a PR for either option if that's useful — just let me know which you'd prefer.

extent analysis

TL;DR

To fix the issue, render the WorkingDirectory in the gateway plist template or resolve agentDir to an absolute path when reading openclaw.json.

Guidance

  • The issue is caused by the combination of a relative agentDir in openclaw.json and the absence of WorkingDirectory in the launchd plist, which defaults to cwd=/.
  • To verify the issue, check the rendered plist for the absence of WorkingDirectory and confirm the default config uses a relative agentDir.
  • A temporary workaround is to insert the WorkingDirectory key manually and reload the launch agent.
  • To mitigate the issue, consider implementing one of the proposed fixes: rendering WorkingDirectory in the gateway plist template or resolving agentDir to an absolute path.

Example

<key>WorkingDirectory</key>
<string>$HOME</string>

This example shows how to render the WorkingDirectory in the gateway plist template.

Notes

The proposed fixes have different trade-offs: rendering WorkingDirectory is a smaller change, while resolving agentDir to an absolute path is more defensive and robust against future service managers.

Recommendation

Apply the workaround by inserting the WorkingDirectory key manually and reloading the launch agent, as this provides a temporary fix until the issue is resolved upstream.

FAIL-SAFE: If the issue persists after applying the workaround, consider sending a PR for one of the proposed fixes.

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

openclaw - 💡(How to fix) Fix gateway launchd plist missing WorkingDirectory → ENOENT on every agent turn (relative agentDir resolves under cwd=/) [2 comments, 3 participants]