Skip to content

[Bug]: Claude thread blocked by auto-mode denials ends as "Completed" instead of needing attention #18386

Description

@teoobarca

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Start a Claude thread with the permission mode set to Auto (Claude Code auto mode).
  2. Get the auto-mode classifier to deny a tool call. The most reliable trigger I hit: the conversation contains detailed security findings (e.g. the agent read a TODO list describing open vulnerabilities, or is fixing an auth bypass). From then on the classifier refuses to assess further Bash calls ("cannot assess the action due to earlier conversation content"). A plain deny rule or any other classifier block behaves the same way.
  3. The agent receives the denial as a failed tool call, can't proceed, and ends its turn.

Expected behavior

The thread signals that it needs me: a "needs attention" status (like a pending approval) instead of "Completed", a row such as "2 actions denied by auto mode" with the classifier's reason, and ideally a one-click "switch to Default / Full access and retry".

Actual behavior

The thread shows Completed and auto-settles. Nothing in the sidebar or the timeline distinguishes "finished the task" from "gave up because auto mode blocked it", so I only notice hours later when I open the thread. In Default mode the same action raises a permission prompt and the thread shows as waiting.

From the source (commit cafe620e):

  • In auto mode no permission callback is installed (ClaudeAdapterV2.ts:1723-1727), and the classifier denies inside the CLI before canUseTool, so no runtime request is ever created.
  • The SDK already reports these denials: every result message carries permission_denials ({tool_name, tool_use_id, tool_input}, visible in the replay fixtures), but no production code reads it; it only appears in tests and fixtures.
  • terminalStatusFromResult (ClaudeAdapterV2.ts:2536-2569) looks only at abort reasons, API errors and is_error, so a successful result with denials becomes completed; ThreadSettlementService.ts:139-164 only holds back for pending requests, active runs or background work.
  • The Grok adapter already turns an auto-mode block into a pending request (testkit/fixtures/grok_auto_blocked_command), so there is precedent.

Possible fix: in the result branch, read permission_denials, drop the tool-use ids T3 itself denied (ExitPlanMode capture, user declines, cancelled questions), and for the rest emit a system notice row and mark the run as needing attention so it isn't auto-settled. Caveat: the entries carry no reason or source, so the reason has to come from the matching tool_result error text.

Impact

Major degradation or frequent failure

Version or commit

0.0.46-nightly.20261011.2967 (source references: cafe620e)

Environment

macOS 26 (Mac mini, T3 server running 24/7), Claude Code 2.1.296, Agent SDK 0.3.276, Claude Max subscription

Workaround

Switch the thread to Full access (or Default) by hand and send "continue". For threads that will touch security-sensitive content, start them in Full access.

Activity

  1. juliusmarminge commented on Oct 11, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    This is a real bug, and I confirmed it in the code on main. In Auto mode, the CLI's classifier blocks tool calls before canUseTool runs, so T3 never creates a pending request. The SDK does list those denials in result.permission_denials, but no production code in ClaudeAdapterV2.ts reads that field. terminalStatusFromResult only checks for aborts, API errors and is_error, so a turn that hit denials still ends as completed and gets auto-settled. The Grok adapter already turns an auto-mode block into a pending request (see the grok_auto_blocked_command fixture), so the Claude adapter is behind on this.

    This isn't a CLI limitation. The denial entries don't include a reason, but the matching tool_result error text does. Open PR #15360 (for #15353) changes Auto mode's ask-rule handling, but it doesn't touch permission_denials or the terminal status mapping, so it won't fix this.

    Scope for a fix:

    • In the result branch, read permission_denials and drop the tool-use ids that T3 denied itself (ExitPlanMode capture, user declines, cancelled questions).
    • For any denials left over, show a notice row with the reason taken from the tool_result, and mark the thread as needing attention so it isn't auto-settled.

    A one-click "switch mode and retry" button is a separate feature, so please suggest it in Ideas. Until this is fixed, switch the thread to Default or Full access and send "continue". Related: #15503.

  2. added
    bugSomething is broken or behaving incorrectly.
    acceptedfeature request accepted
    via-triageFiled through npx t3 triage
    on Oct 11, 2026
  3. juliusmarminge commented on Oct 22, 2026

    @juliusmarminge
    Member

    Fresh triage: this is a reported completion-status bug, not a reported exploitable vulnerability. Scanned all 948 open issues for auto-mode, denial and completion symptoms plus the quoted classifier error; no matching duplicate found. Source inspected at c274a25: Claude result status does not inspect permission_denials. This is source inspection, not runtime reproduction. Changing how permission denials produce attention or settlement state crosses the automated triage approval/mode boundary, so this needs maintainer handling. Leaving the issue open; no code changes or PR.

  4. juliusmarminge commented on Oct 22, 2026

    @juliusmarminge
    Member

    Fresh reproduction on 8acbefefc5: Linux web dev app, Claude CLI 2.1.303, Claude Opus 5.5, Auto mode. A scratch project deny rule for Bash(printf T3_DENIAL_PROBE*) blocked the command; Claude stopped, the native result contained permission_denials, and the persisted run status was completed with no attention request. Two Auto attempts produced the same result. No matching duplicate among 927 open issues; the existing approval-escalation PR addresses a different symptom. Runtime transcript, recording. The earlier permissions-boundary stop no longer applies under the revised triage brief.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedfeature request acceptedbugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions