Plugin hooks fail on npm CLI: %PLUGIN_ROOT% not expanded in commandWindows
What version of Codex CLI is running?
codex-cli 0.145.0
What subscription do you have?
Plus
Which model were you using?
gpt-5.6-terra medium
What platform is your computer?
Windows 10.0.26100 (Windows 11 Professional) [64-bit] x86_64
What terminal emulator and version are you using (if applicable)?
Windows Terminal (PowerShell) PSVersion: 7.6.0
Codex doctor report
{
"schemaVersion": 1,
"generatedAt": "1784701369s since unix epoch",
"overallStatus": "ok",
"codexVersion": "0.145.0",
"checks": {
"app_server.status": {
"id": "app_server.status",
"category": "app-server",
"status": "ok",
"summary": "background server is not running",
"details": {
"control socket": "C:\\Users\\<user>\\.codex\\app-server-control\\app-server-control.sock",
"daemon state dir": "C:\\Users\\<user>\\.codex\\app-server-daemon",
"mode": "ephemeral",
"pid file": "C:\\Users\\<user>\\.codex\\app-server-daemon\\app-server.pid (missing)",
"settings": "C:\\Users\\<user>\\.codex\\app-server-daemon\\settings.json (missing)",
"status": "not running",
"update-loop pid file": "C:\\Users\\<user>\\.codex\\app-server-daemon\\app-server-updater.pid (missing)"
},
"remediation": null,
"durationMs": 0
},
"auth.credentials": {
"id": "auth.credentials",
"category": "auth",
"status": "ok",
"summary": "auth is configured",
"details": {
"auth file": "C:\\Users\\<user>\\.codex\\auth.json",
"auth storage mode": "File",
"stored API key": "false",
"stored ChatGPT tokens": "true",
"stored agent identity": "false",
"stored auth mode": "chatgpt"
},
"remediation": null,
"durationMs": 0
},
"config.load": {
"id": "config.load",
"category": "config",
"status": "ok",
"summary": "config loaded",
"details": {
"CODEX_HOME": "C:\\Users\\<user>\\.codex",
"config.toml": "C:\\Users\\<user>\\.codex\\config.toml",
"config.toml parse": "ok",
"cwd": "D:\\AIWorks\\tracebook",
"enabled feature flags": "<redacted>",
"feature flag overrides": "none",
"feature flags enabled": "36",
"log dir": "C:\\Users\\<user>\\.codex\\log",
"mcp servers": "2",
"model": "gpt-5.6-terra",
"model provider": "openai",
"sqlite home": "C:\\Users\\<user>\\.codex"
},
"remediation": null,
"durationMs": 0
},
"git.environment": {
"id": "git.environment",
"category": "git",
"status": "ok",
"summary": "git version 2.52.0.windows.1",
"details": {
".git entry": "directory",
"PATH git #1": "D:\\App\\Git\\cmd\\git.exe",
"PATH git entries": "1",
"git branch": "master",
"git build options": "git version 2.52.0.windows.1",
"git exec path": "D:/App/Git/mingw64/libexec/git-core",
"git version": "git version 2.52.0.windows.1",
"repo detected": "true",
"repo root": "D:\\AIWorks\\tracebook",
"selected git": "D:\\App\\Git\\cmd\\git.exe"
},
"remediation": null,
"durationMs": 573
},
"installation": {
"id": "installation",
"category": "install",
"status": "ok",
"summary": "installation looks consistent",
"details": {
"PATH codex #1": "C:\\Users\\<user>\\AppData\\Roaming\\npm\\codex",
"PATH codex #2": "C:\\Users\\<user>\\AppData\\Roaming\\npm\\codex.cmd",
"PATH codex entries": "2",
"current executable": "C:\\Users\\<user>\\AppData\\Roaming\\npm\\node_modules\\@openai\\codex\\node_modules\\@openai\\
codex-win32-x64\\vendor\\x86_64-pc-windows-msvc\\bin\\codex.exe",
"install context": "npm",
"managed by bun": "false",
"managed by npm": "true",
"managed by pnpm": "false",
"managed package root": "C:\\Users\\<user>\\AppData\\Roaming\\npm\\node_modules\\@openai\\codex",
"npm update target": "C:\\Users\\<user>\\AppData\\Roaming\\npm\\node_modules\\@openai\\codex"
},
"remediation": null,
"durationMs": 1227
},
"mcp.config": {
"id": "mcp.config",
"category": "mcp",
"status": "ok",
"summary": "MCP configuration is locally consistent",
"details": {
"configured servers": "2",
"disabled servers": "0",
"stdio servers": "2"
},
"remediation": null,
"durationMs": 9
},
"network.env": {
"id": "network.env",
"category": "network",
"status": "ok",
"summary": "network-related environment looks readable",
"details": {
"proxy env vars present": "HTTP_PROXY, HTTPS_PROXY, http_proxy, https_proxy"
},
"remediation": null,
"durationMs": 0
},
"network.provider_reachability": {
"id": "network.provider_reachability",
"category": "reachability",
"status": "ok",
"summary": "active provider endpoints are reachable over HTTP",
"details": {
"ChatGPT base URL": "https://chatgpt.com/backend-api/ reachable (HTTP 403)",
"reachability mode": "ChatGPT auth"
},
"remediation": null,
"durationMs": 375
},
"network.websocket_reachability": {
"id": "network.websocket_reachability",
"category": "websocket",
"status": "ok",
"summary": "Responses WebSocket handshake succeeded",
"details": {
"auth mode": "chatgpt",
"connect timeout": "15000 ms",
"endpoint": "wss://chatgpt.com/backend-api/<redacted>",
"handshake result": "HTTP 101 Switching Protocols",
"model provider": "openai",
"supports websockets": "true",
"wire API": "responses"
},
"remediation": null,
"durationMs": 1456
},
"runtime.provenance": {
"id": "runtime.provenance",
"category": "runtime",
"status": "ok",
"summary": "running npm on windows-x86_64",
"details": {
"commit": "unknown",
"current executable": "C:\\Users\\<user>\\AppData\\Roaming\\npm\\node_modules\\@openai\\codex\\node_modules\\@openai\\
codex-win32-x64\\vendor\\x86_64-pc-windows-msvc\\bin\\codex.exe",
"install method": "npm",
"platform": "windows-x86_64",
"version": "0.145.0"
},
"remediation": null,
"durationMs": 0
},
"sandbox.helpers": {
"id": "sandbox.helpers",
"category": "sandbox",
"status": "ok",
"summary": "sandbox configuration is readable",
"details": {
"approval policy": "OnRequest",
"filesystem sandbox": "restricted",
"network sandbox": "restricted"
},
"remediation": null,
"durationMs": 0
},
"system.environment": {
"id": "system.environment",
"category": "system",
"status": "ok",
"summary": "OS language zh-CN",
"details": {
"os": "Windows 10.0.26100 (Windows 11 Professional) [64-bit]",
"os language": "zh-CN",
"os type": "Windows",
"os version": "10.0.26100"
},
"remediation": null,
"durationMs": 1
},
"terminal.env": {
"id": "terminal.env",
"category": "terminal",
"status": "ok",
"summary": "terminal metadata was detected",
"details": {
"WT_SESSION": "present",
"terminal": "Windows Terminal",
"terminal size": "120x30"
},
"remediation": null,
"durationMs": 0
}
}
}
What issue are you seeing?
Third-party plugin hooks defined with commandWindows in hooks.json always fail with exit code 1 when run from the
npm-installed CLI (@openai/codex@0.145.0).
The same hooks work perfectly in the Codex Desktop App (0.145.0-alpha.30).
Error displayed in CLI:
• UserPromptSubmit hook (failed)
error: hook exited with code 1
• Stop hook (failed)
error: hook exited with code 1
Root cause: The npm CLI binary does not expand %PLUGIN_ROOT% in the commandWindows field before spawning the process.
PowerShell receives the literal string %PLUGIN_ROOT%\hooks\tracebook_hook.ps1 as a file path, cannot find the file, and exits
with code 1.
I verified this by manually running the command:
```powershell
# With %PLUGIN_ROOT% unexpanded — FAILS (same as npm CLI behavior):
echo '{}' | powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "%PLUGIN_ROOT%\hooks\tracebook_hook.ps1"
# Error: file not found, exit code 1
# With the actual path — WORKS (same as Desktop App behavior):
echo '{"hook_event_name":"UserPromptSubmit","cwd":"D:\\AIWorks\\tracebook"}' | powershell.exe -NoProfile -NonInteractive
-ExecutionPolicy Bypass -File "C:\Users\<user>\.codex\plugins\cache\tracebook\tracebook\2.0.1\hooks\tracebook_hook.ps1"
# exit code 0, outputs correct JSON
Affected plugin: tracebook v2.0.1 — a durable project knowledge plugin that provides lifecycle hooks via hooks.json for both Claude
Code and Codex.
What steps can reproduce the bug?
1. Install the [tracebook](https://github.com/tydandou/tracebook) plugin (or any plugin with `commandWindows` hooks that reference
`%PLUGIN_ROOT%`):
- Add marketplace to `config.toml`:
```toml
[marketplaces.tracebook]
source_type = "git"
source = "https://github.com/tydandou/tracebook.git"
ref = "v2.0.1"
```
- Enable the plugin:
```toml
[plugins."tracebook@tracebook"]
enabled = true
```
2. Trust the hooks when prompted
3. Run `codex` from terminal (npm CLI) and submit any prompt
4. Observe: `UserPromptSubmit hook (failed) error: hook exited with code 1`
5. End the session — observe: `Stop hook (failed) error: hook exited with code 1`
**Contrast:** Open the same project in Codex Desktop App → hooks execute successfully.
### What is the expected behavior?
The npm CLI binary should expand `%PLUGIN_ROOT%` (and `$PLUGIN_ROOT` on Unix) in hook command strings to the plugin's cached
directory before spawning the process, consistent with the Desktop App behavior.
Expected `%PLUGIN_ROOT%` resolution for this plugin:
`C:\Users\<user>\.codex\plugins\cache\tracebook\tracebook\2.0.1`
The hooks.json `commandWindows` field:
```json
"%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File
\"%PLUGIN_ROOT%\\hooks\\tracebook_hook.ps1\""
Should be expanded at runtime to:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File
"C:\Users\<user>\.codex\plugins\cache\tracebook\tracebook\2.0.1\hooks\tracebook_hook.ps1"
### Additional information
```markdown
- The Desktop App binary (`~/.codex/plugins/.plugin-appserver/codex.exe`, version 0.145.0-alpha.30) correctly expands
`%PLUGIN_ROOT%` — the same hooks work there without any issue.
- The npm CLI binary is at:
`~\AppData\Roaming\npm\node_modules\@openai\codex\node_modules\@openai\codex-win32-x64\vendor\x86_64-pc-windows-msvc\bin\codex.exe`
- This likely affects ALL third-party plugins that use `commandWindows` with `%PLUGIN_ROOT%` on the npm CLI.
- The tracebook plugin ([github.com/tydandou/tracebook](https://github.com/tydandou/tracebook)) is a cross-platform plugin designed
for both Claude Code and Codex. Its hooks work correctly on Claude Code and Codex Desktop, only failing on the npm CLI
distribution.
- `config.toml` shows the hooks are trusted (have `trusted_hash` entries), confirming Codex did parse and register them — the issue
is purely at execution time.