Permission rejection misattributed to "the user" with no visible prompt — auto-mode; plus need for a self-diagnosis/bug-report skill

Status Open
Maintainer reply None cached
Activity 0 comments · opened Jul 20, 2026

Title

Permission rejection is silently attributed to "the user" with no visible prompt — causes indefinite hangs in unattended/auto-mode sessions

Summary

In defaultMode: "auto", when a Bash tool call includes a subcommand that doesn't match any permissions.allow/ask rule, the tool call is rejected with the message:

"The user doesn't want to proceed with this tool use. The tool use was rejected"

No permission prompt was ever shown or answered by the user. The rejection message language falsely implies explicit human denial, and the agent (and the user, reading the transcript later) has no way to distinguish "a real person clicked deny" from "no prompt appeared and something else declined it." For unattended sessions (background tasks, forked agents, scheduled workflows), this means the run just stops silently with no actionable signal — indistinguishable from a hang, sometimes for hours/days before a human notices.

Repro

  1. Global ~/.claude/settings.json has:

``json
"permissions": {
"allow": ["Bash(git worktree:*)", "Bash(git branch:*)", ...],
"ask": ["Bash(git branch -D:*)", "Bash(git branch --delete:*)", ...],
"defaultMode": "auto"
}
``

  1. Agent runs a compound command:

``
cd /path/to/repo && git worktree remove .worktrees/foo && git branch -d fix/some-branch
``

  1. Per documented behavior (permissions.md, "compound commands"), Claude Code parses shell operators and evaluates each subcommand independently:
  • cd — no-op
  • git worktree remove .worktrees/foo — matches Bash(git worktree:*) → allowed
  • git branch -d fix/some-branch — lowercase -d matches neither the allow list nor the ask list (only -D/--delete are listed)
  1. Expected: an interactive permission prompt for the unmatched git branch -d subcommand, since defaultMode is auto (which should ask on anything not explicitly allowed).
  2. Actual: the tool call is rejected outright with "The user doesn't want to proceed," and no prompt is ever visibly shown to the user. The user, watching the terminal live, confirms no prompt appeared at any point.

Why this matters

  • The rejection text is misattributed — it should never say "the user doesn't want to proceed" unless a human actually answered "no" to a rendered prompt.
  • If a policy/mode is doing the declining (not the user), the message must say so explicitly, distinctly from a real user decline.
  • In unattended contexts (background Bash, forked agents, scheduled/cron workflows, Workflow tool subagents), a swallowed rejection like this has no recovery path — the run just stops. This is very likely the cause of tasks/agents reported as "hanging" for minutes to days: they aren't hung, they silently died on an unmatched permission check with no surfaced signal.

Ask

  1. Fix (or confirm intended behavior of) the mismatch: an unmatched subcommand under defaultMode: auto should trigger a visible prompt, not a silent rejection.
  2. Never phrase an automated/policy-driven decline as "the user doesn't want to proceed" — reserve that language strictly for an actual answered prompt; use distinct wording for anything else (timeout, policy auto-deny, missing UI surface for a background session, etc.).
  3. For any tool call rejected without a human-answered prompt (e.g., permission checks running in a background/unattended agent with no UI to render a prompt to), surface that explicitly to the invoking context — don't let it look identical to a live user "no."

Environment

  • Claude Code, defaultMode: auto
  • macOS (darwin), zsh
  • Also present in settings but unverified/possibly irrelevant: an undocumented top-level key skipAutoPermissionPrompt: true in ~/.claude/settings.json, not found in current permissions/settings docs (defaultMode, disableAutoMode, disableBypassPermissionsMode, permissionExplainerEnabled are the documented ones). Worth checking whether this key is read by the current version at all, and if so what it does — since its name alone suggests it could plausibly cause exactly this symptom.

Note on my own in-session investigation (reporter caveat)

While diagnosing this live, Claude (in-session) initially attributed the cause to compound-command allowlist matching (cmd1 && cmd2 not matching a single-command allow rule). The reporting user pushed back: compound commands have always been standard in how Claude Code and its agents issue Bash calls, and auto-mode has handled them fine historically — so that explanation doesn't hold up as the actual root cause here, even though the compound-matching behavior itself was confirmed against current docs. The true root cause of the silent, unattributed rejection is still unconfirmed.

This points to a second, meta-level gap worth fixing:

  1. Claude Code (and Claude agents generally) should not answer questions about how Claude Code itself works from memory/assumption. They should be required to check current version docs/changelog within the session before asserting behavior, and clearly flag anything unconfirmed as unconfirmed — not stated as fact.
  2. There should be a built-in diagnostic path for "tool behavior doesn't match the explanation given." When an agent's stated reasoning for a tool result doesn't hold up (as happened here), there's currently no structured way to re-diagnose systematically — it's ad hoc back-and-forth.
  3. There should be an easy, low-friction way to extract the relevant session details into a well-formed bug report — the raw ingredients (settings, exact command, exact tool-result text, timeline) — rather than requiring the user to manually walk the agent through reconstructing evidence.

Suggested product fix: a built-in skill/mode for "Claude Code behaved unexpectedly" that (a) forces a fresh docs/changelog check for the running version before any explanation is given, (b) runs a structured inconsistency check between claimed behavior and observed tool output, and (c) packages the findings into a submittable bug report automatically.

View original on GitHub ↗