Plugin errors

Common error signatures

Failures in the plugin's hooks fall into three categories:

Where errors originate

Function Module What goes wrong
main() hooks._handoff_cli Entry point for /handoff; any unhandled exception from the call chain surfaces here as a non-zero exit
build_resume_prompt() hooks._resume_prompt Receives None for spec_info when discovery found nothing; downstream templates render without spec context
discover_specs() hooks._state Raises on unreadable specs/ directories; returns an empty list when roots are empty
git_state() hooks._state Raises when cwd is not a git repo or git is unavailable
session_sentinel_path() hooks._state Raises when the resolved path is unwritable
estimate_utilization() hooks._transcript_size Raises on a missing or unreadable transcript file
validate_bash_command() / validate_file_path() hooks.security_guard Returns (False, reason) — not an exception, but the main() caller must check the boolean

How to diagnose

  1. Identify the hook entry point that failed. Each hook module exposes a main() function. The hook name in the error output (handoff, compact_warning, spec_orient, security_guard, and so on) tells you which main() was active when the failure occurred.

  2. Check whether discover_specs() returned an empty list. If workspace_roots() found no roots, discover_specs() receives an empty roots list and returns []. This produces no exception — the symptom is a silent no-op in format_orientation() or a build_resume_prompt() call where spec_info is None.

  3. Verify git availability for git_state() failures. Run git rev-parse --show-toplevel in the working directory. If that fails, git_state() will fail for the same reason, and GitState.branch, GitState.last_sha, and GitState.last_subject will be unpopulated.

  4. For security guard rejections, check the return value, not the exception. validate_bash_command() and validate_file_path() signal rejection via (False, reason_string) — they do not raise. If a command or path is being silently blocked, print the second element of the return tuple to read the rejection reason. Blocked path prefixes include everything under SYSTEM_DIRECTORIES: /etc, /sys, /proc, /dev, /boot, /sbin, /usr/sbin, /private/etc, and /private/var.

  5. For utilization warnings that never appear, confirm that the transcript file passed to estimate_utilization() exists and is readable. A missing transcript causes an exception that prevents format_warning() from composing the warning and resume prompt.

Source files

Tags: plugin, claude-code