Skip to content

SessionEnd hook fails with "Hook cancelled" when exiting Claude Code #7

Description

@ipfans

When using the claude-code-logfire-plugin, the SessionEnd hook fails with Hook cancelled.

claude --dangerously-skip-permissions

Resume this session with:
claude --resume deb8dd09-3866-4472-886e-25660570a0eb
SessionEnd hook [python3 "$CLAUDE_PLUGIN_ROOT/scripts/log-event.py"] failed: Hook cancelled

Root Cause Analysis

handle_session_end performs blocking network calls to the OTLP endpoint:

  1. Eager send_otlp() at line 1165
  2. acquire_lock() — up to 5s if contended
  3. Second send_otlp() at line 1211 (if new transcript data)

Each send_otlp() has a 5-second urlopen timeout. In my environment the actual round-trip is ~3 seconds (this may vary — it could be higher due to local network conditions, geographic distance to the Logfire US endpoint, or transient network issues), but any non-trivial latency triggers the problem.

The issue is not timeout — the SessionEnd hook has a 30-second timeout which should be sufficient. The error is "Hook cancelled" (process killed), meaning Claude Code sends SIGTERM to hook process groups during session teardown, before the configured timeout is reached. This is Claude Code's exit-time behavior: it kills child processes as part of shutdown regardless of hook timeout settings.

Since send_otlp() is a blocking network call, even a few hundred milliseconds of latency creates a window where the process can be killed mid-flight.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions