Skip to content

fleet: concurrent PostToolUse hook writes can silently clobber each other (no locking/ordering) #875

Description

@kyle-sexton

Summary

Claude Code runs every matching PostToolUse hook in parallel for one tool call. Multiple hooks in this fleet write to the same edited file with no locking or ordering primitive between them:

Any file matched by both an unscoped writer and a scoped formatter (e.g. any .py file, with eol-normalizer and ruff-format both applicable — or, once #872 merges, typos-format and ruff-format on any .py file governed by both a typos config and a Ruff config) has two hooks independently reading-then-writing the same file with no coordination. A nondeterministic clobber is possible: whichever write lands last silently discards the other's fix.

Surfaced explicitly during #872's stress-test and independent review; documented (not fixed) in typos-format's hook header comment and README "Known limitation" section as a pre-existing, fleet-wide gap this single plugin cannot address.

Impact

Low-frequency (requires two applicable hooks + concurrent scheduling), but silent when it hits — no error, no diagnostic, just a dropped fix. Grows with every new unscoped or overlapping-scope hook plugin added to the fleet.

Constraints

No native Claude Code feature exists today for sequential/ordered hook execution within one event (verified during #872's research). Any fix is either:

  1. A convention/pattern this repo's hooks adopt (e.g. a shared file lock via flock, already used elsewhere in hook::append_jsonl).
  2. An upstream feature request to Claude Code for ordered or serialized PostToolUse hook execution.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.priority: mediumReal value, no hard deadline; normal backlog flow.wayfind: designWayfind decision item: design-space or domain-model decision; human in the loop.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions