`headersHelper` on `type:"http"` hooks silently ignored since ≤2.1.209 — no changelog, no deprecation, no unknown-field warning

Status Fixed / completed
Reported on v2.1.209
Maintainer reply None cached
Activity 1 comment · opened Jul 17, 2026 · closed Aug 21, 2026

Summary

Claude Code no longer executes the headersHelper script referenced by type:"http" hook entries. The field is silently ignored: the helper process is never spawned, and the hook POST goes out with no injected headers. There was no changelog entry, no deprecation warning, and no startup diagnostic — configs that were previously valid degrade to unauthenticated requests with no client-side signal. (MCP-server headersHelper is unaffected and still documented.)

Impact

Our fleet telemetry pipeline (14 http hook entries POSTing session/tool/permission events to a backend) ran header-less for weeks: every request 401'd server-side while the client showed only per-event hook error / HTTP 401 lines with no hint that an auth-config field had been dropped. Anyone using headersHelper for hook auth is silently broken.

Repro / evidence

  • Verified on 2.1.209, 2.1.211, 2.1.212 (macOS), interactive sessions (http hooks do not fire in -p headless mode, which complicates repro — worth documenting too).
  • Instrumented the helper script (unconditional side-effect on invocation): zero invocations across many hook firings, while the hook POSTs did go out (server logged them arriving with no Authorization header).
  • Replacing headersHelper with the current documented contract — "headers": {"Authorization": "Bearer $VAR"} + "allowedEnvVars": ["VAR"] — immediately restores auth (A/B tested per-entry against the same endpoint).
  • headersHelper has zero mentions in the current hooks docs (https://code.claude.com/docs/en/hooks.md); the changelog mentions it only in MCP-server contexts.

Related: other silently-ignored hook fields

While migrating we found the same failure mode with additional fields, suggesting a general gap:

  • status_message (snake_case) is silently ignored — the docs specify statusMessage. A wrong-cased field simply does nothing.
  • fail_mode does not appear in the hooks docs field tables (common/command/http) or the changelog at all, yet configs carrying it (e.g. "fail_mode": "ignore" on http entries) load without complaint.

Ask

  1. A startup (or config-load) warning on unknown/unrecognized hook fields — this single diagnostic would have surfaced the break in one session instead of weeks.
  2. Changelog/deprecation notes when a config field is removed or renamed.
  3. Docs note that http hooks don't fire in -p headless mode (affects anyone trying to reproduce hook issues scriptably).

Environment

Claude Code 2.1.212, macOS (darwin 25.5), hooks delivered via a plugin marketplace (type:"http" entries in a plugin's hooks.json).

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗