-
-
Notifications
You must be signed in to change notification settings - Fork 69.5k
[Bug]: Dashboard returns 404 on Windows with pnpm global install because control-ui files are hardlinked #40108
Description
Bug type
Regression (worked before, now fails)
Summary
Dashboard root returns 404 on Windows when OpenClaw is installed globally with pnpm, because dist/control-ui files are installed as hardlinks and the static UI files are not served.
Steps to reproduce
- On Windows, install OpenClaw globally with:
pnpm add -g openclaw@latest --config.auto-install-peers=false - Start the gateway.
- Run:
openclaw dashboard --no-open - Open the printed dashboard URL, for example:
http://127.0.0.1:18789/#token=... - Observe that:
http://127.0.0.1:18789/healthreturns200http://127.0.0.1:18789/readyreturns200http://127.0.0.1:18789/__openclaw/control-ui-config.jsonreturns200http://127.0.0.1:18789/returns404http://127.0.0.1:18789/index.htmlreturns404
- Inspect the installed UI file and note that it is a hardlink:
...node_modules/openclaw/dist/control-ui/index.html
Expected behavior
The dashboard URL printed by openclaw dashboard --no-open should open the Control UI successfully, and / should serve the dashboard HTML.
Actual behavior
The gateway is healthy and Control UI config routes are present, but the dashboard root returns 404.
Observed:
/health->200/ready->200/__openclaw/control-ui-config.json->200/->404/index.html->404
As a workaround, copying dist/control-ui to a normal directory and setting gateway.controlUi.root to that directory makes / and /index.html return 200.
OpenClaw version
2026.3.7 (42a1394)
Operating system
Windows 10 x64 (10.0.19045)
Install method
Global install with pnpm: pnpm add -g openclaw@latest --config.auto-install-peers=false
Logs, screenshots, and evidence
Gateway status was healthy while dashboard root still failed.
HTTP evidence:
- `http://127.0.0.1:18789/health` -> `200`
- `http://127.0.0.1:18789/ready` -> `200`
- `http://127.0.0.1:18789/__openclaw/control-ui-config.json` -> `200`
- `http://127.0.0.1:18789/` -> `404`
- `http://127.0.0.1:18789/index.html` -> `404`
The installed file is a hardlink:
PowerShell:
Get-Item "D:\pnpm-global\5\.pnpm\[email protected]_@[email protected]\node_modules\openclaw\dist\control-ui\index.html" | Format-List FullName,Attributes,LinkType,Target
Output included:
LinkType : HardLink
Node evidence:
const fs = require("fs");
const st = fs.lstatSync("D:/pnpm-global/5/.pnpm/[email protected]_@[email protected]/node_modules/openclaw/dist/control-ui/index.html");
console.log({ isSymbolicLink: st.isSymbolicLink(), nlink: st.nlink, size: st.size });
Output:
{ isSymbolicLink: false, nlink: 2, size: 692 }
Workaround that fixed it:
1. Copy dist/control-ui to a normal directory
2. Set:
{
"gateway": {
"controlUi": {
"enabled": true,
"root": "C:\\Users\\lp\\.openclaw\\control-ui"
}
}
}
3. Restart gateway
After that:
/ -> 200
/index.html -> 200
/__openclaw/control-ui-config.json -> 200Impact and severity
- Affected users/systems/channels:
Windows users installing OpenClaw globally withpnpm, especially when dashboard access is needed. - Severity:
Blocks dashboard/control UI usage, but gateway and channels can still run. - Frequency:
Deterministic in this environment. - Consequence:
Users cannot access the dashboard even though the gateway is healthy, which makes onboarding, configuration, and debugging much harder.
Additional information
This does not look like a gateway auth problem or a missing asset build problem.
The Control UI config endpoint is present and returns 200, so the gateway is mounting Control UI-related routes. The failure appears specific to serving static files from the pnpm-installed dist/control-ui directory.
This looks like a Windows + pnpm hardlink interaction with OpenClaw's static file serving / safe-open logic.
I did not verify whether the same issue occurs with:
- npm global install
- the Windows installer
- WSL
- a source checkout
In this environment, overriding gateway.controlUi.root to a copied non-hardlinked directory is a reliable workaround.