#645·ponytail

POSIX hooks error (exit 127) when Node.js is not on PATH — Windows variant is guarded, POSIX is not

Author: NinjasnazCreated Jul 29, 2026Updated Sep 30, 2026

Summary

On macOS/Linux hosts without Node.js on PATH, every ponytail hook fires a hook_non_blocking_error because the POSIX hook command invokes node unconditionally. The Windows variant guards for a missing node, but the POSIX variant does not.

Version: 4.8.4 (Claude Code plugin, hooks/claude-codex-hooks.json)

Root cause

Each hook entry defines two commands:

json
"command":        "node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-activate.js\"",
"commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { node \"$env:CLAUDE_PLUGIN_ROOT\\hooks\\ponytail-activate.js\" }"

The Windows command checks Get-Command node before running. The POSIX command has no equivalent guard, so when node is absent it exits 127 (node: command not found), which Claude Code records as a non-blocking hook error.

This affects all three POSIX hooks:

  • SessionStart → ponytail-activate.js
  • SubagentStart → ponytail-subagent.js
  • UserPromptSubmit → ponytail-mode-tracker.js

Reproduction

  1. macOS/Linux machine with no node on PATH.
  2. Install/enable the ponytail plugin in Claude Code.
  3. Start a session and submit a prompt.

Observed: SessionStart:startup and UserPromptSubmit produce hook_non_blocking_error on every session start and prompt submission (fast, 12–38 ms, non-blocking, but noisy).

Direct reproduction:

$ echo '{}' | node "$CLAUDE_PLUGIN_ROOT/hooks/ponytail-activate.js"
zsh: command not found: node   # exit 127

Suggested fix

Mirror the Windows guard on POSIX, e.g.:

json
"command": "command -v node >/dev/null 2>&1 && node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-activate.js\" || true"

so the hook no-ops cleanly when Node.js isn't installed, matching the existing Windows behavior.

Environment

  • ponytail 4.8.4
  • Claude Code 2.1.212 (Homebrew, macOS / darwin arm64)
  • Node.js: not installed