#Agent failed before reply: EACCES: permission denied, mkdir '/Users/morebetter/.openclaw/agents/main

1 messages · Page 1 of 1 (latest)

orchid nimbus
#

Agent failed before reply: EACCES: permission denied, mkdir '/Users/morebetter/.openclaw/agents/main/agent'.

ebon mortarBOT
#

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

empty glenBOT
#

That error is basically: the Gateway process can’t write to your OpenClaw state dir, so it can’t create the embedded agent directory at:

/Users/morebetter/.openclaw/agents/main/agent

Most common cause: you (or the installer) ran OpenClaw once with a different user (often sudo), and now parts of ~/.openclaw are owned by root or have weird ACLs.

First, what version + how are you running it?

  • openclaw --version
  • Are you starting via OpenClaw.app (menu bar) or via CLI/launchd?

Quick diagnosis (paste output):

ls -ldOe ~/.openclaw ~/.openclaw/agents ~/.openclaw/agents/main 2>/dev/null || true

Typical fix (macOS): make your user own the state dir again, then restart the gateway/app.

#
sudo chown -R "$USER":staff ~/.openclaw
chmod -R u+rwX ~/.openclaw

If ~/.openclaw is a symlink to an external drive / network volume, that can also cause this—so if the ls -ldOe output shows a symlink, mention where it points.

Docs reference for where these paths come from (and how OPENCLAW_HOME / OPENCLAW_STATE_DIR can affect it): https://docs.openclaw.ai/help/environment

orchid nimbus
#

OpenClaw 2026.3.13 (61d171a)
OpenClaw.app (menu bar)

drwx------+ 16 morebetter 1000 - 512 16 Mar 13:14 /Users/morebetter/.openclaw
0: user:mbclaw allow list,add_file,search,add_subdirectory,delete_child,readattr,writeattr,readextattr,writeextattr,readsecurity
drwx------ 6 morebetter 1000 - 192 16 Mar 13:44 /Users/morebetter/.openclaw/agents
drwx------+ 5 morebetter 1000 - 160 27 Feb 21:28 /Users/morebetter/.openclaw/agents/main
0: user:mbclaw allow list,add_file,search,add_subdirectory,delete_child,readattr,writeattr,readextattr,writeextattr,readsecurity

empty glenBOT
#

Nice, the ls -ldOe output is super telling:

  • ~/.openclaw has an ACL entry for user mbclaw
  • ~/.openclaw/agents does not (no +, no ACL lines)
  • yet the failing path is under ~/.openclaw/agents/...

So this is almost certainly: your running Gateway process is not morebetter (it’s likely running as mbclaw), and it can’t traverse/write ~/.openclaw/agents, hence the EACCES on the mkdir.

1) Confirm which user is actually running the Gateway

Run one of these and paste output:

lsof -nP -iTCP:18789 -sTCP:LISTEN
ps ax -o user,pid,command | grep -i "openclaw gateway" | grep -v grep

If you see mbclaw there, that’s the smoking gun.

#

2) Fix (recommended): make the macOS app use the per-user LaunchAgent for morebetter

From the morebetter terminal:

openclaw gateway stop
openclaw gateway install --force
openclaw gateway restart

Then re-check lsof ...18789 to ensure it’s listening as morebetter.

3) Fix (workaround): if you intentionally run the gateway as mbclaw

You need to grant mbclaw access to the missing directory too:

chmod +a "user:mbclaw allow list,add_file,search,add_subdirectory,delete_child,readattr,writeattr,readextattr,writeextattr,readsecurity" ~/.openclaw/agents
#

But I’d only do this if you really want that split-user setup.

Paste the lsof/ps output and I’ll tell you which branch you’re in.

orchid nimbus
#

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 23115 mbclaw 15u IPv4 0x556ba8430b2a18bd 0t0 TCP 127.0.0.1:18789 (LISTEN)
node 23115 mbclaw 16u IPv6 0xf4f7a87873d1e927 0t0 TCP [::1]:18789 (LISTEN)

empty glenBOT
#

Yup — that confirms it: the Gateway listening on 18789 is running as mbclaw, not morebetter.

That’s why it blows up trying to create stuff under /Users/morebetter/.openclaw/... (it’s the wrong user for that state dir; and your ~/.openclaw/agents dir has no ACL for mbclaw).

Recommended fix: run the Gateway as morebetter (so it matches the app + home dir)

1) Stop the mbclaw gateway (PID 23115)

Try the clean stop first:

sudo -u mbclaw -H openclaw gateway stop

If that command isn’t available in mbclaw’s PATH, use launchd to identify + unload it:

#
launchctl print pid/23115 | head -n 30

(or as a blunt last resort: sudo kill 23115)

2) Make sure the port is free

lsof -nP -iTCP:18789 -sTCP:LISTEN

(should show nothing)

3) Start it as morebetter

From your normal morebetter terminal:

#
openclaw gateway install --force
openclaw gateway restart

Then re-check:

lsof -nP -iTCP:18789 -sTCP:LISTEN

You want to see USER = morebetter.


Workaround (if you intentionally want gateway to run as mbclaw)

Add the missing ACL so mbclaw can write into ~/.openclaw/agents too:

#
chmod +a "user:mbclaw allow list,add_file,search,add_subdirectory,delete_child,readattr,writeattr,readextattr,writeextattr,readsecurity" ~/.openclaw/agents

…but I’d still recommend the “run as morebetter” route for the menu-bar app setup.

If you paste the first ~30 lines of launchctl print pid/23115, I can tell you exactly what job label to bootout so it doesn’t come back.

orchid nimbus
#

I killed the pid but lsof showed another pid, So I did launchctl :launchctl print pid/43323
pid/43323 = {
type = pid
handle = 43323
active count = 1
on-demand count = 1
originator = /opt/homebrew/Cellar/node/25.6.1/bin
creator = node[43323]
creator euid = 502
uniqueid = 43323
security context = {
uid = 502
asid = 100021
}

xpc service paths = {
}
death port = 0x9148f

environment = {
    PATH => /opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin
    HOME => /Users/mbclaw
    TMPDIR => /var/folders/8j/63rkz4dx0431v4y21k01ql180000gp/T/
}

services = {
}

unmanaged processes = {
}

endpoints = {
}

task-special ports = {
           0xa03 4       bootstrap  com.apple.xpc.launchd.domain.pid.node.43323
          0x2b03 9          access  (unknown)
}

resource coalition = {
    ID = 559
    type = resource
    state = active
    active count = 1
    name = ai.openclaw.gateway
}

jetsam coalition = {
    ID = 560
    type = jetsam
    state = active
    active count = 1
    name = ai.openclaw.gateway
}


properties = 

}

orchid nimbus
#

can you see which job label I need to boot out

empty glenBOT
#

Not from here — I can’t see your launchctl output. But you can get the exact job label (and whether it’s system vs gui/<uid>) directly from that PID.

Run this and paste the output (first ~60 lines is usually enough):

launchctl print pid/23115 | sed -n '1,80p'

If you just want to extract the key lines locally:

launchctl print pid/23115 | egrep -i 'domain|service|label|name|path|origin'

Then boot it out based on the domain it reports

  • If it says it’s in a user GUI domain (something like gui/…), do:
#
id -u mbclaw
sudo launchctl bootout gui/<MBCLAW_UID>/<LABEL>
  • If it says it’s in the system domain, do:
sudo launchctl bootout system/<LABEL>

launchctl print pid/23115 often also shows an “origin path” / plist path — if you paste that line too, I can tell you exactly which plist to remove so it doesn’t respawn.

orchid nimbus
#

lsof -nP -iTCP:18789 -sTCP:LISTEN
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 43323 mbclaw 20u IPv4 0x8664545eaf9a1275 0t0 TCP 127.0.0.1:18789 (LISTEN)
node 43323 mbclaw 21u IPv6 0x4d173ee135847da 0t0 TCP [::1]:18789 (LISTEN)
mbclaw@MoreBetters-Mac-mini ~ % launchctl print pid/43323 | egrep -i 'domain|service|label|name|path|origin'
originator = /opt/homebrew/Cellar/node/25.6.1/bin
xpc service paths = {
PATH => /opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin
services = {
0xa03 4 bootstrap com.apple.xpc.launchd.domain.pid.node.43323
name = ai.openclaw.gateway
name = ai.openclaw.gateway

empty glenBOT
#

Yup — you’ve got the label right there:

Job label: ai.openclaw.gateway

Since it’s running as the mbclaw user, boot it out of mbclaw’s GUI domain:

If you’re in a terminal as mbclaw

launchctl bootout gui/$(id -u)/ai.openclaw.gateway

If you’re in a terminal as morebetter

sudo launchctl bootout gui/$(id -u mbclaw)/ai.openclaw.gateway

Then confirm it’s gone:

#
lsof -nP -iTCP:18789 -sTCP:LISTEN

After that, the menu-bar app (running as morebetter) should be able to start/attach to a morebetter-owned gateway cleanly. If it doesn’t auto-start, run as morebetter:

openclaw gateway install --force
openclaw gateway restart

If you want to prevent mbclaw’s service from coming back on login, also check/remove its LaunchAgent plist:
/Users/mbclaw/Library/LaunchAgents/ai.openclaw.gateway.plist (move it aside rather than deleting if you’re unsure).

orchid nimbus
#

from terminal as mbclaw, launchctl bootout gui/$(id -u)/ai.openclaw.gateway
it says Boot-out failed: 3: No such process

#

lsof -nP -iTCP:18789 -sTCP:LISTEN
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 43323 mbclaw 20u IPv4 0x8664545eaf9a1275 0t0 TCP 127.0.0.1:18789 (LISTEN)
node 43323 mbclaw 21u IPv6 0x4d173ee135847da 0t0 TCP [::1]:18789 (LISTEN)

empty glenBOT
#

bootout …/<label> returning No such process usually means there isn’t a loaded launchd job with that exact label in that domain (even though the process is running and its “name” shows ai.openclaw.gateway).

Let’s do it the reliable way: bootout by plist path, and/or confirm whether a plist exists.

1) As mbclaw, check if there’s a LaunchAgent plist

ls -la ~/Library/LaunchAgents | grep -i openclaw

If you see something like ai.openclaw.gateway.plist (or ai.openclaw.<profile>.plist), boot it out by path:

launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist

(Adjust the filename if it’s ai.openclaw.<profile>.plist.)

#

2) If there’s no LaunchAgent, it might be a system LaunchDaemon

sudo ls -la /Library/LaunchDaemons | grep -i openclaw

If found:

sudo launchctl bootout system /Library/LaunchDaemons/<that-plist>.plist

3) If neither plist exists, it’s probably just a manually-started process

Then just stop it directly:

kill 43323
# or: killall node   (only if you’re sure you won’t nuke other node things)
#

After any of the above, re-check:

lsof -nP -iTCP:18789 -sTCP:LISTEN

Paste the ls …LaunchAgents output and I’ll tell you the exact plist/command to use.

orchid nimbus
#

found ai.openclaw.gateway.plist , then did : sudo launchctl bootout system /Library/LaunchDaemons/ai.openclaw.gateway.plist ; lsof return blank so it looks kicked out.

empty glenBOT
#

Perfect — that explains everything.

/Library/LaunchDaemons/ai.openclaw.gateway.plist is a system LaunchDaemon, so it can run under a different user (mbclaw) and still grab port 18789. The macOS menu-bar app then happily attaches to “whatever is already listening”, which is why you ended up with mbclaw trying to write into /Users/morebetter/.openclaw/... → EACCES.

Next steps (to fully finish the fix)

  1. Make sure the daemon doesn’t come back on reboot
    Booting out stops it now, but LaunchDaemons usually reload on reboot if the plist is still there. Easiest: move it aside:
sudo mv /Library/LaunchDaemons/ai.openclaw.gateway.plist \
        /Library/LaunchDaemons/ai.openclaw.gateway.plist.disabled
  1. Start the per-user gateway as morebetter
    Either toggle “OpenClaw Active” off/on in the menu-bar app, or from a morebetter terminal:
#
openclaw gateway install --force
openclaw gateway restart
  1. Verify it’s now running as morebetter
lsof -nP -iTCP:18789 -sTCP:LISTEN

You should see USER = morebetter.

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

orchid nimbus
#

for sudo mv /Library/LaunchDaemons/ai.openclaw.gateway.plist
/Library/LaunchDaemons/ai.openclaw.gateway.plist.disabled, it says ai.openclaw.gateway.plist.disabled is not a directory

empty glenBOT
#

That mv error usually happens when the command got pasted in a way that made mv think you had multiple sources, or the destination got interpreted weirdly.

Do this as a clean one-liner (no line breaks):

sudo mv -v /Library/LaunchDaemons/ai.openclaw.gateway.plist /Library/LaunchDaemons/ai.openclaw.gateway.plist.disabled

Or (even safer to paste) with brace expansion:

sudo mv -v /Library/LaunchDaemons/ai.openclaw.gateway.plist{,.disabled}

If it still complains, first show what actually exists:

#
ls -la /Library/LaunchDaemons/ai.openclaw.gateway.plist*

Paste that output and I’ll tell you the exact filename/path to rename (sometimes there’s a suffix or you already renamed it once).

orchid nimbus
#

ls -la /Library/LaunchDaemons/ai.openclaw.gateway.plist*. returned no matches found

#

Looks like the plist file does not exist. I logged in as morebetter and installed gateway then restarted. Now it shows morebetter listening

#

how do I get the browser chat interface to show

empty glenBOT
#

Perfect — that’s the clean end state you want:

  • nothing in /Library/LaunchDaemons anymore grabbing the port as mbclaw
  • gateway installed/restarted under morebetter
  • lsof shows morebetter listening on 18789
  • the EACCES mkdir /Users/morebetter/.openclaw/agents/main/agent should be gone now because the runtime user matches the state dir owner

If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes it for the next person who hits the “wrong launchd user grabbed the port” issue.

orchid nimbus
#

one more thing , how do I get the browser chat interface to show

empty glenBOT
#

To get the browser chat / Control UI:

  1. Make sure the gateway is running (sounds like it is now):
openclaw gateway status
  1. Open the dashboard in your browser (recommended because it handles auth nicely):
openclaw dashboard

(or if you don’t want it to auto-launch a browser: openclaw dashboard --no-open)

  1. Alternatively, just open this URL directly on the Mac running the gateway:

If the page loads but shows Disconnected / Unauthorized (1008), you need to give it the gateway auth:

#
  • In the Control UI go to Control → Overview → Gateway Access
  • Paste your Gateway Token (or password) and click Connect
  • You can print the token from the gateway host with:
    openclaw config get gateway.auth.token
    

Docs: https://docs.openclaw.ai/web/dashboard

#

The “browser chat interface” is the Control UI (Dashboard).

Fastest way (because it figures out the right URL + basePath + auth flow):

openclaw dashboard

That should open your browser straight to the UI. Once it loads, use the Chat tab/section.

If you want to open it manually, check what base path you’re using:

openclaw config get gateway.port
openclaw config get gateway.controlUi.basePath
#

Then open:

  • http://127.0.0.1:<port><basePath>/

Commonly that ends up being either:

  • http://127.0.0.1:18789/ or
  • http://127.0.0.1:18789/openclaw/

If the UI loads but says Unauthorized / Disconnected, paste your token in Control → Overview → Gateway Access (Gateway Token field) and hit Connect.