Skip to content

fix: PreToolUse↔canUseTool FIFO desync corrupts tool-call correlation when tools are auto-allowed #81

Description

@saucam

Summary

The PreToolUse hook enqueues a {toolUseId, agentId} entry keyed by tool name for every tool call, but the matching dequeue happens only in canUseTool — which the Agent SDK does not invoke for auto-allowed tools. Any allow-rule desyncs the FIFO and corrupts tool-call correlation for the rest of the session.

Location

  • src/daemon/providers/claude/index.ts:297-303 (enqueue in PreToolUse)
  • src/daemon/providers/claude/index.ts:350-359 (dequeue in canUseTool)
  • allowedTools at :262-264; settingSources: ["project"] at :296 (loads .claude/settings.json permissions.allow)
  • consumer correlation in src/daemon/session.ts:1937-1948

Root cause

canUseTool is skipped by the SDK for tools matched by allowedTools or by a project permissions.allow rule. The hook still pushed an entry for those, so the queue holds stale entries that the next gated tool pops.

Failure scenario

Repo has .claude/settings.json"allow": ["Bash(git status:*)"]. Agent runs git status (hook enqueues under "Bash", canUseTool never fires), then runs a gated rm -rf build. canUseTool pops the stale git status entry → tool_start emitted with the wrong sdkToolUseId#toolUseIdToMessageId mismatches → the real tool_complete finds no message (tool shows running forever) and later output can attach to the wrong tool message in scrollback and canonical history.

Secondary defect (same site)

Entries for always-allowed tools (e.g. mcp__codeoid_memory__recall) are never popped, so #pendingToolUse grows unbounded over an hours-long session.

Fix

Correlate by the SDK's real tool_use_id end-to-end rather than a name-keyed FIFO, or also drain the queue from the PostToolUse/result path so auto-allowed tools don't leave stale heads. Bound the map regardless.

Metadata

Metadata

Assignees

No one assigned

    Labels

    auditSurfaced in a code auditbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions