Claude Code stops on a permission prompt when you are away. How to fix it.

A Claude Code agent that stalls on a permission prompt while you are away is fixed by changing its permission mode, pre-approving the commands it needs, and routing the few prompts that no mode can auto-approve. The fastest single change is to put the session in auto mode, where a classifier reviews actions instead of you.

Updated October 20, 2026.

The rest of this page covers what causes the stall, the four fixes in the order worth trying, the floor that no configuration removes, and what to do when the agent that stalled is one of four agents in four different projects.

Why a Claude Code agent stalls when nobody is watching

A Claude Code agent stalls because a tool call reached a decision that only a person can make, and Claude Code waits rather than guess. Four different things produce that same frozen screen, and they have different fixes.

Cause What the agent is actually doing Fixed by
A tool call needs approval and no rule covers it Waiting on a permission prompt A permission mode, or an allow rule
An action no mode auto-approves Waiting on a prompt that cannot be pre-approved Routing the prompt to you
AskUserQuestion Asking you a question, not asking permission Routing the question to you
The turn ended Nothing. The agent finished and is idle Noticing sooner

The last row matters more than it looks. An agent that finished twenty minutes ago and an agent blocked on an approval produce the same still terminal, so “my agent is stuck” and “my agent is done and I did not notice” are the same observation until you read the screen.

In Manual mode, which Claude Code’s config files call default, only reads run without asking. File edits, shell commands outside a built-in read-only set, web fetches, and web searches all prompt. A session left in Manual mode on an open-ended task will stop within a few minutes, every time, and that is the mode behaving as designed.

Fix 1: change the permission mode

Changing the permission mode fixes more stalls than anything else on this page, and on current versions it may already be done for you. Claude Code’s permission modes are:

Mode What runs without asking
default (shown as Manual) Reads only
acceptEdits Reads, file edits, and common filesystem commands such as mkdir, touch, mv, cp
plan Reads, plus classifier-approved commands where auto mode is available
auto Everything, with a background classifier checking actions first
dontAsk Pre-approved tools and reads in the working directories. Anything that would prompt is denied
bypassPermissions Everything

Anthropic’s permission-modes documentation states that with Claude Code v2.1.283 or later, auto mode is the built-in starting permission mode for interactive terminal and VS Code sessions; on earlier versions it was the starting mode only on Pro, Max, and Team plans. In auto mode a second model, the classifier, reviews shell commands and network requests before they run, instead of you. Reads and working-directory edits skip the classifier entirely.

Switch the mode of a running session with Shift+Tab in the terminal. Set it for a new one with a flag:

claude --permission-mode auto

Make it the default for every session with defaultMode in a settings file:

{
  "permissions": {
    "defaultMode": "auto"
  }
}

Two honest limits on auto mode. It needs a supported model, and an organization can turn it off with permissions.disableAutoMode. On Enterprise plans and on accounts using the Claude API, Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry, classifier calls count toward token usage, because each check sends part of the transcript plus the pending action.

bypassPermissions is the mode people pick after the third stall, and it is the one to be careful with. It skips prompts including writes to protected paths such as .git and .claude. Anthropic’s documentation says to use it only in isolated environments like containers or VMs. “I want my agent to keep going while I am at lunch” is not that environment.

Fix 2: pre-approve the specific commands

Pre-approving commands with allow rules stops the prompts you can predict, and leaves the ones you cannot. Run /permissions to see every rule and which settings file it came from, or write the rules directly:

{
  "permissions": {
    "allow": [
      "Bash(npm test)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Read",
      "Edit"
    ]
  }
}

The rule syntax is Tool or Tool(specifier). A bare tool name matches every use of that tool. The space before the * in Bash(git diff *) is load-bearing: without it, Bash(git diff*) would also match git diff-index.

The cheapest way to build this list is to stop choosing “Yes” on prompts and start choosing Yes, and don’t ask again. For a Bash command or a WebFetch domain, Claude Code saves that rule to .claude/settings.local.json at the root of the git repository, and it applies to future sessions anywhere in that repository, including subdirectories and worktrees. File-modification approvals are the exception: they last until the session ends and are not written to the file.

Allow rules are enforced by Claude Code, not by the model. An instruction in your prompt or in CLAUDE.md shapes what Claude tries to do and changes nothing about what Claude Code permits.

Fix 3: run it headless, with the prompts turned off

For a scheduled or unattended run, headless mode removes the question of who answers a prompt. Pass -p with the prompt and name the tools:

claude -p "Run the test suite and fix any failures" \
  --allowedTools "Bash,Read,Edit"

For a job where nobody is available at all, --permission-prompts none (Claude Code v2.1.259 or later) is the flag that matters. With it, the run consults no permission host and waits on none. Anything that would prompt is denied unless a PermissionRequest hook allows it, Claude is told that nobody can approve the request and not to retry it, and the run continues:

claude -p "Update the dependency pins and run the tests" \
  --permission-mode auto --permission-prompts none

Read that trade carefully, because it is a real trade. --permission-prompts none and dontAsk do not get the agent past the decision. They convert an indefinite stall into a denial, so the run finishes instead of hanging, having skipped the thing it wanted to do. For a CI gate that is correct. For “write the migration while I am out,” a denied run that reports success on half the work is worse than a stall you find at 2pm.

Fix 4: hooks, which push the prompt somewhere you are

Hooks are the fix that works when the prompt genuinely needs a human and the human is not at that keyboard. Claude Code fires hook events around permission decisions, and two of them matter here.

  • PermissionRequest can answer the prompt. In modes that ask, a PermissionRequest hook decides the request instead of the dialog.
  • PreToolUse returns a decision in hookSpecificOutput.permissionDecision, whose values are allow, deny, ask, and defer. It can also rewrite the tool input via updatedInput before the call runs.
  • Notification fires when Claude Code sends a notification, and its matcher filters on the notification type. The two types worth wiring are permission_prompt and idle_prompt.

A Notification hook matching permission_prompt is the mechanism behind the write-ups people publish about fixing this with hooks. One developer’s account on dev.to forwards permission requests into Slack to grant or deny them from a phone, and names the constraint that makes the whole exercise necessary: permission prompts are a local thing, and they show up in the terminal rather than anywhere you happen to be.

That constraint is the honest centre of this problem. A hook can tell you a prompt exists. Answering it still means reaching the session that raised it.

The floor: prompts that no configuration removes

Some prompts wait for a person no matter which mode or rule you set, and it is worth knowing them so you stop trying to configure them away. Anthropic documents these as the actions no mode auto-approves, including bypassPermissions:

  • Tools matched by an explicit ask rule
  • Connector tools your organization set to ask
  • Tools that require user interaction: the built-in AskUserQuestion tool, and MCP tools marked requiresUserInteraction
  • rm and rmdir removals targeting a critical path, which no allow rule and no PreToolUse "allow" approves
  • The cross-session messaging safeguards
  • Reads outside the working directories while permissions.blockReadsOutsideWorkingDirectories is on

One of these has a thoughtful escape hatch worth knowing. In auto and bypassPermissions modes, the prompt for a critical-path removal shows a two-minute countdown, and if the countdown runs out Claude Code denies the command and tells Claude what to do instead, so an unattended session keeps working rather than hanging forever.

Everything else on that list waits indefinitely. AskUserQuestion is the common one in practice: the agent is not asking for permission, it is asking you which of three approaches to take, and no permission setting answers a question. So the goal is not zero prompts. The goal is that the prompts which remain reach you fast and can be answered from wherever you are.

Where the single-agent fixes run out

The four fixes above are sized for one agent in one project, and they stop fitting at three or four agents across different repositories. Three specific things break.

You cannot pre-approve open-ended work across several repositories. An allow list is a prediction about which commands a task needs. It holds for a tight task in a familiar repo and it does not hold for “look into why staging is slow.” Multiply that by four projects with four different toolchains and the list stops converging.

One mode is the wrong granularity. The settings file that makes a dependency-bump agent productive is the wrong setting for the agent touching auth. A global auto or a global bypassPermissions applies your loosest judgment to your most sensitive repository.

A notification that does not say which agent is not much better than silence. With one session, “something needs permission” is a complete message. With five, the missing half of the message is which project, which session, and what it wants to run. You get the alert, then do the tab-hunting anyway, which is the tab-hunting problem with an extra step.

At that point the problem has changed shape. It is no longer “stop the prompts.” It is routing: every waiting agent in one list, each prompt attributed to its project and session, answerable without finding the terminal it came from.

How crystl handles the prompts that still wait

crystl is a macOS terminal built for the multi-project case, and it treats the approval as something to route rather than something to eliminate. Three parts do the work.

Auto-approval is set per project, not globally. crystl intercepts the approval request and applies that project’s auto-approval mode: off (everything waits), in gem (reads anything, changes only inside this project’s tree, safe git only, asks for the rest), or all. One sentence is the whole contract for the middle mode, and it is the one most work runs under. The setting lives per gem, so the dependency-bump project and the auth project do not share a judgment.

A permission mode declared inside a repository may narrow what crystl auto-approves and may never widen it. A .claude/agents/*.md file that declares permissionMode: bypassPermissions grants nothing extra under in gem. That matters because anyone who can write that file, an agent with write access included, would otherwise have unattended command execution.

A waiting prompt is attributed and reachable. A pending approval surfaces as a floating card carrying the tool name, the working directory, Allow and Deny buttons, and a session-colored glow that says which session asked. When several queue up, an Allow All bar appears. Answer from the keyboard with Cmd+Return to allow or Cmd+Esc to deny, scoped to the project in front of you so a pending approval in another project cannot be answered by accident. A card for a session already on your screen is withheld, because the terminal is already the notification.

The project tiles in the crystal rail carry a red badge counting what needs a human, and the badge heats up as its oldest waiting item ages, so a prompt that has sat for ten minutes stops looking like one that arrived ten seconds ago.

An agent can be asked, in one command, who is waiting. crystl pending lists pending approvals, crystl shards --all flags a parked session as ⏸ awaiting input across every project in one call, and crystl wait pending --timeout 60 blocks until the next one arrives rather than polling. Those three are free on every tier. Answering from the CLI, crystl approve and crystl deny, is a Guild control command; without it you click Allow or Deny on the card.

For the case in the title, where you are not at the computer at all, the iPhone app pairs to your Mac and opens on the agents that are waiting on you, so an approval can be answered from a phone. Same Wi-Fi is free; connecting from outside your network routes through an encrypted relay and is a Guild feature.

Three limits worth stating plainly. crystl is macOS only. The depth of approval surfacing varies by agent: it is deepest for Claude Code, partial for Codex, and other CLI agents are supervised at the terminal level. And crystl does not remove the floor described above, because nothing does. AskUserQuestion still needs an answer. It changes how fast you find out and how far you have to go to give it.

The short version

  • One agent, familiar repo: auto mode plus a handful of allow rules. Most of this problem disappears.
  • A scheduled or CI run: claude -p with --allowedTools, and --permission-prompts none so a prompt becomes a denial instead of a hang. Accept that the run may finish having skipped something.
  • Fully unattended and permissive: bypassPermissions inside a container or VM, never on your working machine.
  • A prompt that genuinely needs you: a PermissionRequest hook to answer it programmatically, or a Notification hook matching permission_prompt to push it somewhere you are.
  • Several agents across several projects: the binding constraint is routing, not prompt elimination. Per-project modes, attributed cards, and one list of who is waiting.

Related reading: monitoring several agents at once, the tmux setup people build for parallel agents and why a terminal multiplexer cannot tell a blocked agent from a thinking one, and what a Claude Code GUI should actually do.

crystl is free. Sign up at crystl.dev/login.