Plugin monitors/monitors.json auto-arm silently fails on 2.1.118
Summary
Claude Code 2.1.118 does not auto-arm monitors declared in a plugin's monitors/monitors.json at session start. The docstring for Monitor tool / plugin loading (in the 2.1.118 binary) states that persistent monitors declared in monitors.json at the plugin root are armed as persistent Monitor tasks at session start. In practice, none of the declared monitors spawn processes. Plugin loading itself works (skills, hooks, MCP servers all load correctly) — only monitor auto-arm is affected.
Environment
- Claude Code: 2.1.118 (
/Users/<user>/.local/bin/claude) - Platform: macOS 25.4.0 (darwin arm64)
- Launched via:
--plugin-dir /path/to/plugin
Plugin structure
.claude-plugin/plugin.json:
{
"name": "vault",
"version": "1.0.0",
"description": "...",
"skills": "./skills/",
"hooks": "./hooks/hooks.json",
"monitors": "./monitors/monitors.json"
}
monitors/monitors.json (excerpt — 6 monitors declared):
{
"monitors": [
{
"name": "vault-file-changes",
"description": "Vault file change watcher ...",
"command": "${CLAUDE_PLUGIN_ROOT}/bin/vault-watch.sh",
"persistent": true
},
{
"name": "build-watcher",
"description": "Build error watcher ...",
"command": "${CLAUDE_PLUGIN_ROOT}/bin/build-watch.sh",
"persistent": true
}
// ...4 more monitors, all persistent or one-shot
]
}
All referenced scripts exist, are executable, and run correctly when invoked directly.
Expected behavior
At session start, Claude Code arms each monitor in monitors.json as a persistent Monitor task (per docstring). ps should show one child process per declared monitor under the claude PID.
Actual behavior
No monitor processes are spawned. After ~3 minutes of session uptime:
$ ps -axo pid,ppid,command | grep -E 'vault-watch|build-watch' | grep -v grep
(no output)
However, other plugin-loaded artifacts do spawn correctly. Under the current claude PID (e.g. 31687):
31696 31687 node /path/to/obsidian-mcp-server/dist/index.js # MCP server ✓
31697 31687 node /path/to/apple-mail-calendar-mcp/dist/... # MCP server ✓
31712 31687 node /path/to/tdx-kb-mcp-server/dist/... # MCP server ✓
…so plugin loading is working. Only monitor auto-arm is silent.
Manually invoking the same monitors via the Monitor tool from within the session works correctly — the scripts run and stream events as expected. The failure is specific to the session-start auto-arm path.
Reproduction
- Create a plugin with a valid
.claude-plugin/plugin.jsondeclaring"monitors": "./monitors/monitors.json". - Populate
monitors/monitors.jsonwith any persistent monitor. - Launch a session with
--plugin-dir <plugin>. - After session start,
ps -axo pid,ppid,command | grep <monitor-script>— expect one child under claude PID; observe zero.
Impact
Plugin authors relying on monitors.json for observability (vault-watchers, build-watchers, log-tails) silently get no coverage. Because the failure is silent, users tend to work around it by arming monitors from within skills (e.g., inline Monitor tool calls at skill startup), which makes the bug invisible in day-to-day use and hard to discover.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗