Skip to content

docs: hooks run in stripped environment — settings.json env.PATH is a required but undocumented field #1368

Description

@DonovanJonesUK

Summary

When Claude Code hooks execute (PreToolUse, PostToolUse, Stop, etc.), they run in a non-interactive shell with no .bashrc, no .zshrc, and no user PATH. The only PATH available to hooks is the one explicitly set in the env block of ~/.claude/settings.json.

This means tools like rg, fd, bun, and rtk — all of which PAI hooks invoke — are invisible to hooks even when correctly installed on the system, unless their directories appear in settings.json env.PATH.

Current State

This is not documented anywhere in PAI. HookSystem.md, CLAUDE.md, and CliFirstArchitecture.md don't mention the stripped environment. The failure mode is completely silent: hooks that depend on missing-PATH tools either skip (if they have guards) or fail with opaque errors, with no signal to the user.

Discovery

Found on a Hetzner VPS (Ubuntu 24.04) when the ContextReduction hook was silently skipping every Bash call because rtk and rg weren't on the hook PATH — despite being correctly installed on the system. The hook guard (if ! command -v rtk &>/dev/null; then exit 0; fi) masked the degradation entirely. The issue only surfaced during a full PAI tool audit triggered by an unrelated fd: command not found error in a dropped session recovery.

Proposed Fix

  1. Add a "Hook Execution Environment" section to HookSystem.md explicitly stating that hooks run in a stripped shell with no inherited PATH, and that settings.json env.PATH must be set explicitly.
  2. Add a post-install checklist item to CliFirstArchitecture.md or a new SETUP.md: verify settings.json has an explicit PATH covering ~/.local/bin, ~/.bun/bin, and any tool directories PAI depends on.

Example Correct Configuration

{
  "env": {
    "PATH": "/home/{user}/.local/bin:/home/{user}/.bun/bin:/usr/local/bin:/usr/bin:/bin"
  }
}

Note: the PATH value must be a literal string — shell variable expansion (e.g. ${HOME}) does not apply in this context.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions