Skip to content

[fix] Added can_use_tool callback and prompt change to prevent AskUserQuestion error#294

Merged
calreynolds merged 1 commit intodatabricks-solutions:mainfrom
riley-mete-db:riley/ask-user-question
Mar 11, 2026
Merged

[fix] Added can_use_tool callback and prompt change to prevent AskUserQuestion error#294
calreynolds merged 1 commit intodatabricks-solutions:mainfrom
riley-mete-db:riley/ask-user-question

Conversation

@riley-mete-db
Copy link
Contributor

AskUserQuestion Tool Failures in Downstream UIs

Problem

When Claude calls the AskUserQuestion tool during a builder-app agent session, it produces is_error=True tool results. In downstream applications that proxy builder-app events, this renders as a red "Failed" status in the UI. The agent may also stop entirely instead of asking questions as normal text.

Root Cause

The builder-app runs claude-agent-sdk with permission_mode='bypassPermissions' and no can_use_tool callback (agent.py:454).

bypassPermissions auto-allows regular tools (Bash, Write, etc.) at the CLI level without ever sending a control request to the SDK. However, AskUserQuestion is different — it requires structured user answers (questions + answers payload), so the CLI still sends a can_use_tool control request to the SDK.

With no callback registered, the SDK raises:

Exception("canUseTool callback is not provided")

Source: claude_agent_sdk/_internal/query.py:241-242

This error is returned to the CLI as a control protocol error response, which the CLI converts into a ToolResultBlock with is_error=True.

Resolution

Two-layer fix applied:

1. System prompt instruction (primary)

Tells Claude not to use AskUserQuestion and to ask questions directly in text responses instead. This prevents the tool from being called in the first place.

File: server/services/system_prompt.py

- **Do NOT use the AskUserQuestion tool.** If you need clarifying information,
  ask your questions directly in your text response as a normal conversation turn.
  The user will reply naturally.

2. can_use_tool callback (safety net)

Intercepts AskUserQuestion with PermissionResultAllow and synthetic answers that redirect Claude to ask questions in text. Returns a successful result — no is_error, no red "Failed" in downstream UIs. All other tools pass through as auto-allowed.

Requires a PreToolUse keepalive hook per the Python SDK requirement. No websocket, no timeout concerns, no architectural changes — the callback returns immediately with a static response.

File: server/services/agent.py

async def can_use_tool(
    tool_name: str, input_data: dict, _context: ToolPermissionContext,
) -> PermissionResultAllow | PermissionResultDeny:
    if tool_name == "AskUserQuestion":
        questions = input_data.get("questions", [])
        answers = {
            q.get("question", ""): "Please ask this question directly in your text response."
            for q in questions
        }
        return PermissionResultAllow(
            updated_input={"questions": questions, "answers": answers},
        )
    return PermissionResultAllow(updated_input=input_data)

async def _keepalive_hook(_input_data, _tool_use_id, _context):
    return {"continue_": True}

options = ClaudeAgentOptions(
    ...
    can_use_tool=can_use_tool,
    hooks={"PreToolUse": [HookMatcher(matcher=None, hooks=[_keepalive_hook])]},
    ...
)

Files Changed

File Change
server/services/system_prompt.py Added "Do NOT use AskUserQuestion" to Tool Usage section
server/services/agent.py Added can_use_tool callback, _keepalive_hook, PermissionResult* / ToolPermissionContext imports

Documentation

@calreynolds calreynolds merged commit 8649236 into databricks-solutions:main Mar 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants