Hooks errors
Common error signatures
Errors in the hook system typically fall into three categories:
- Configuration errors —
HookConfig.from_yaml()raises when the YAML file is missing, malformed, or contains an unrecognizedHookEventorHookTypevalue. - Executor errors —
HookExecutor.execute()orHookExecutorSync.execute()raises when aHookDefinitionreferences a Python handler name that was not registered in thepython_handlersdict passed to the constructor. - Registry dispatch errors —
HookRegistry.fire()orHookRegistry.fire_sync()raises when an event fires but the underlying executor fails, or whenregister()is called with an invalidpriorityor aHookMatcherwhosematches()method raises unexpectedly. - Script hook errors —
run_evaluate_session(),apply_learned_patterns(), orrun_pre_compact()raises when thecontextdict is missing expected keys, or wheninitialize_project()cannot create the required.attunesubdirectories.
Where errors originate
The following functions are the most common raise sites. The symptom you observe upstream — a hook silently not firing, a fire() call returning no results, or a script handler crashing — usually traces back to one of these:
HookConfig.from_yaml()— fails fast if the YAML path does not exist or the file does not parse into a validHookConfig.HookExecutor.execute()/HookExecutorSync.execute()— fails if theHookDefinitionrequests a Python handler that is absent frompython_handlers.HookRegistry.fire()/HookRegistry.fire_sync()— propagates executor errors for every matching rule; inspectget_execution_log()immediately after a failedfire()call to see which rules ran and which did not.run_evaluate_session()/apply_learned_patterns()— fail when thecontextdict passed by the hook lifecycle is incomplete.initialize_project()— fails with a filesystem error if the process lacks write permission to create directories underINIT_DIRECTORIES(.attune,.attune/sessions, etc.).
How to diagnose
-
Read the execution log first. Call
HookRegistry.get_execution_log()(optionally withevent_filter) immediately after a failedfire()orfire_sync()call. The log shows whichHookRuleandHookDefinitionwere attempted and where execution stopped. -
Check
get_stats()for silent failures. Iffire()returns an empty list when you expected results, callHookRegistry.get_stats()to verify that hooks are registered for the event and that theHookMatcher.matches()call is returningTruefor your context. -
Validate your
HookConfigin isolation. Load the config withHookConfig.from_yaml()and callget_hooks_for_event()for the relevantHookEventbefore wiring it into aHookRegistry. This confirms the YAML parsed correctly and the right rules are present. -
Verify Python handler registration. If the error message indicates an unresolved handler, confirm that every handler name referenced in your
HookDefinitionobjects appears as a key in thepython_handlersdict you passed toHookExecutororHookExecutorSync. -
Check context keys for script hooks.
run_evaluate_session(),apply_learned_patterns(), andrun_pre_compact()all receive acontext: dict[str, Any]. Print the context dict at the call site and compare it against the keys the script expects — missing keys are the most common cause ofKeyErrorin these handlers.
Source files
src/attune/hooks/**
Tags: hooks, webhooks, events, automation