AskUserQuestion auto-resolves with empty answers in Agent SDK programmatic mode (canUseTool never awaited)
Description
When using the Claude Agent SDK (@anthropic-ai/claude-agent-sdk v0.2.63) programmatically with query(), the AskUserQuestion tool auto-resolves with empty answers even though a canUseTool callback is provided that should block until the user responds.
The canUseTool callback correctly awaits a Promise for user input, but the SDK appears to resolve AskUserQuestion internally before canUseTool completes, producing:
User has answered your questions: . You can now continue with the user's answers in mind.
SDK-Specific Context (Not CLI)
This is distinct from the CLI-based reports in #29530, #30207, #30679. We're using the Agent SDK to build a desktop app (Electron + Hono server) where:
query()is called withcanUseToolcallbackcanUseTooldetectsAskUserQuestion, creates a pending Promise, emits an SSE event to our frontend- The frontend should render a question UI, user selects answers, frontend POSTs response back
- The POST resolves the Promise,
canUseToolreturns{behavior: "allow", updatedInput: {answers: ...}}
What actually happens: The SDK resolves the tool instantly (same-second DB timestamp for tool_use and tool_result) without waiting for canUseTool to return.
Reproduction
import { query } from "@anthropic-ai/claude-agent-sdk";
const res = query({
prompt: channel.generator(firstMessage),
options: {
permissionMode: "default", // NOT bypassPermissions
canUseTool: async (toolName, input, options) => {
if (toolName === "AskUserQuestion") {
// This Promise should block until user responds via UI
const response = await waitForUserResponse(options.toolUseID);
return {
behavior: "allow",
updatedInput: { ...input, answers: response.answers },
};
}
// ... other tools
},
},
});
for await (const message of res) {
// tool_use and tool_result for AskUserQuestion arrive in the same iteration
// with 0 seconds between them — canUseTool was never awaited
}
Evidence from DB Timestamps
We persisted all SDK messages to SQLite. For three separate AskUserQuestion calls in the same conversation:
| Tool Call ID | tool_use timestamp | tool_result timestamp | Gap |
|---|---|---|---|
| toolu_011pB2xD35TxBkSBbzpvxygU | 07:51:57 | 07:51:57 | 0s |
| toolu_0123mappWTVAJsbmjRGcEpps | 07:54:03 | 07:54:03 | 0s |
| toolu_01Sk2owtJbZfEDQ3BTS1Yopu | 07:55:46 | 07:55:46 | 0s |
All three resolved with empty answers: "User has answered your questions: ." — the user never saw any question UI.
SDK Source Analysis
In the minified cli.js (v0.2.63), the AskUserQuestion tool has:
requiresUserInteraction(){return!0}— should forcecanUseToolto be calledcheckPermissionsreturns{behavior:"ask"}— should trigger thecanUseToolflowcall({questions, answers={}})— defaultsanswersto{}if not provided
The permission dispatch logic does route to canUseTool for tools with requiresUserInteraction: true. However, something in the execution pipeline resolves the tool before canUseTool's async return value is awaited.
Impact
Critical for SDK users building custom UIs. The canUseTool callback is the documented mechanism for intercepting AskUserQuestion in programmatic mode, but it's effectively a no-op — the tool resolves before the callback completes.
Environment
- SDK:
@anthropic-ai/claude-agent-sdkv0.2.63 - Platform: macOS (Darwin 25.3.0, Apple M4 Pro)
- Node: v22
- Permission mode:
default(notbypassPermissions) - App: Electron desktop app using SDK's
query()with long-lived sessions viaMessageChannelgenerator pattern
Related Issues
- #29530 — Same symptoms in CLI mode (open, 23 upvotes)
- #10400 — Fixed for
bypassPermissionsbut notdefaultmode - #30207, #30679, #30563, #30523 — Various related reports
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗