AskUserQuestion PreToolUse hook's defer() hits claude-code#64389 race — fix: use allow instead

Open Beginner friendly
#2,292 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
typescript
Domain
devtools

Research direction

Start in hosts/claude/hooks/question-preference-hook.ts and inspect defer(), then check hosts/claude/hooks/auq-error-fallback-hook.ts and other AskUserQuestion PreToolUse hooks for the same pattern. Verify the pass-through path uses allow while the enforcement deny path remains unchanged, and confirm repeated AskUserQuestion calls no longer produce the reported missing tool result.

Written by the indexing model from the issue text.

Description

Bug

hosts/claude/hooks/question-preference-hook.ts's pass-through path (the common case: a plain AskUserQuestion call with no <gstack-qid:...> marker, or one that doesn't match a never-ask preference) resolves via:

function defer(additionalContext?: string): void {
  const out = { hookEventName: 'PreToolUse', permissionDecision: 'defer', ... };
  process.stdout.write(JSON.stringify({ hookSpecificOutput: out }));
  process.exit(0);
}

This hits a confirmed Claude Code SDK race: anthropics/claude-code#64389 — a PreToolUse hook resolving permissionDecision: "defer" can lose a race in the SDK and get fed a fabricated is_error: true, "[Tool result missing due to internal error]" tool_result instead of suspending correctly. A commenter on that thread confirms it reproduces against AskUserQuestion specifically, not just Bash.

Since this hook matches every AskUserQuestion / mcp__*__AskUserQuestion call, and the pass-through defer() branch is what fires for any plain question without gstack's internal marker (i.e. most real usage, any time a skill or the base agent asks a free-form question), this made AskUserQuestion unreliable-to-broken in the Claude Code VS Code extension host in my testing — deterministically failing across repeated calls in one session.

Root cause is upstream, but the workaround is local

The claude-code#64389 thread has two purported fixes:

  1. Delay the defer() write until after the assistant message stream closes (~200ms, reported as "deterministic across dozens of runs" by one reporter).
  2. Use allow/deny/ask instead of defer — the thread states plainly these are not affected by the race.

I tried (1) first; it did not reproduce reliably in my environment — still failed after adding the delay. Switched to (2): since AskUserQuestion has no real "normal permission system" step for defer to fall through to (unlike a gated Bash command), swapping the pass-through case to permissionDecision: "allow" is behaviorally equivalent here, and it resolved the issue — confirmed working across repeated live calls afterward.

Suggested fix

In defer() in question-preference-hook.ts (and check auq-error-fallback-hook.ts / any other PreToolUse hook using defer for AskUserQuestion for the same pattern), change:

permissionDecision: 'defer',

to

permissionDecision: 'allow',

for the pass-through case specifically (the enforcement deny() path is unaffected and doesn't need to change). Happy to open a PR with this if useful — for now filing as an issue since I wasn't sure whether you'd want this landed as-is or handled differently upstream (e.g. if defer is relied on elsewhere for permission-mode interop I haven't considered).

Environment

  • CLAUDE_CODE_ENTRYPOINT=claude-vscode, Claude Code VS Code extension, agent SDK 0.3.207, macOS.
Dominant language
TypeScript
Stars
134k
Forks
19.9k
Avg merge
20h 59m
Merged PRs (30d)
21

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from garrytan/gstack

All issues in garrytan/gstack

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.