New to Claude Skills? Learn how to install them →

Claude Code's --permission-prompts none Flag Explained

Claude Code's --permission-prompts none flag denies anything that would need a person to answer, instead of hanging a scheduled or unattended run waiting for input that never comes.

September 4, 2026
Get Claude Skills
7 min read

The problem it solves

A scheduled job or CI pipeline that runs claude -p has no one sitting at a terminal. If Claude Code hits a permission request that nothing else resolves, an unanswered AskUserQuestion call, an MCP tool an admin marked for manual review, an elicitation prompt from a connector, the run has traditionally just hung there. In print mode, the default handling (host) sends that request to whatever answers it: an Agent SDK app's canUseTool callback, or a tool you supplied with --permission-prompt-tool. Without either of those wired up, the request simply waits for an answer that is never coming.

--permission-prompts none, added in Claude Code v2.1.259 (2 September 2026), removes that failure mode. Pass it and Claude Code denies anything that would have needed a person, immediately, and tells Claude plainly that nobody can approve the request so it should not retry. The run keeps going instead of stalling.

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

That's the example Claude Code's own headless documentation gives, and it's a good illustration of why the flag exists separately from a permission mode. Auto mode's classifier already approves or denies most actions without asking anyone. --permission-prompts none only changes what happens to the smaller remainder the classifier would otherwise have escalated to a human, the requests permission modes were never designed to resolve on their own.

What --permission-prompts actually controls

The flag has two accepted values:

  • host (the default): permission prompts go to the Agent SDK host's canUseTool callback, or to a tool passed with --permission-prompt-tool. If neither exists, the run waits.
  • none: nothing is consulted. Anything that would prompt is denied unless a PermissionRequest hook allows it first.

It's worth being precise about the layering here, because it's easy to assume the flag decides what gets checked. It doesn't. Permission rules, any PermissionRequest hooks you've configured, and the permission mode you're running under all still make their normal decisions first. --permission-prompts none is the fallback for whatever is left over after those have run their course and would otherwise have needed a human. In an already-unattended -p run with no host configured at all, those leftover requests were being denied anyway; the flag's second effect, telling Claude not to bother retrying them, is what actually changes.

What gets denied, specifically

With the flag set, Claude Code removes tools that need a person to answer from the session outright, most notably AskUserQuestion, so Claude cannot call them at all rather than calling them and being refused. Any MCP elicitation request that no Elicitation hook answers is cancelled rather than left pending.

If you're running with --output-format stream-json, every denial this causes shows up as a permission_denied system message as it happens, and the final result message includes the complete set in its permission_denials field. That gives you a clean audit trail of exactly what a given unattended run couldn't do, which matters if you're debugging why a scheduled task came back with less done than you expected.

Where this fits among Claude Code's other headless controls

SettingQuestion it answersDefault
--permission-mode (auto, dontAsk, acceptEdits, etc.)What gets approved automatically in the first placemanual in print mode on every plan
--permission-prompt-toolWhich external tool answers a prompt that isn't auto-approvednone configured
--permission-promptsWho answers a prompt that isn't auto-approved and has no --permission-prompt-toolhost
--dangerously-skip-permissionsWhether to skip permission checks almost entirely (bypassPermissions)off

Print mode's built-in starting permission mode is Manual on every plan, which is exactly why an unattended -p invocation needs an explicit mode. dontAsk is the other option worth knowing here: it denies anything not covered by your permissions.allow rules or the built-in read-only command set, useful for a locked-down CI runner that should never have escalated in the first place. acceptEdits lets Claude write files without prompting and auto-approves common filesystem commands like mkdir, touch, mv, and cp, but still needs an allow rule for other shell commands and network requests.

None of those three replace --permission-prompts none. They decide what counts as approved. The flag decides what happens to what's left after that decision has already gone against auto-approval.

Why the default (host) isn't enough for most unattended runs

The host default makes sense for the case the flag wasn't built for: an Agent SDK application embedding Claude Code, where your own code supplies a canUseTool callback and genuinely wants the chance to decide, in real time, whether a given tool call should proceed. That's a legitimate pattern, and it's why host stays the default rather than none. The problem is what happens when that host doesn't exist, which is the common case for a plain claude -p invocation fired from cron, a GitHub Action, or a scheduled Claude Code routine: there is no canUseTool callback and no --permission-prompt-tool either, so a request that reaches this point has nowhere to go. Before v2.1.259, that request simply sat unanswered until whatever wrapped the process (a job timeout, a CI step limit) killed it from the outside, usually with a log that doesn't clearly say why. --permission-prompts none gives that same unattended run an explicit, documented outcome instead of an implicit hang.

This is also why the flag is scoped to print mode only. An interactive session already has someone at the keyboard to answer a prompt, so there's no equivalent gap to close there; --permission-prompts has no effect outside -p.

A worked example: a scheduled dependency bump

Say you run a weekly job that asks Claude Code to bump dependency pins and confirm the test suite still passes, with no one watching it fire. Before this flag, if the classifier or your permission rules ever escalated a single action (an unusual npm subcommand, say, that your rules didn't anticipate), the job would sit there until a timeout killed it, having made partial progress and left an ambiguous log.

claude -p "Update the dependency pins in package.json and run the test suite. Report any failures." \
  --permission-mode auto \
  --permission-prompts none \
  --output-format stream-json

Now that same edge case resolves immediately: auto mode's classifier reviews the action, and anything it would otherwise have punted to a human is denied instead. Claude sees the denial, is told not to retry, and works around it or reports it in the final summary. You get a completed run with a clear record of what it couldn't do, rather than a job that never returned.

This pairs naturally with the patterns in how to self-host Claude Code runners and Claude Code Routines, both of which assume nobody is present to click "yes" when the CLI asks.

Troubleshooting

The flag is rejected as an unknown option. --permission-prompts requires Claude Code v2.1.259 or later. Check your version with claude --version and upgrade if you're on an earlier release; older versions don't recognise it at all.

Claude keeps trying the same denied action. That shouldn't happen with the flag set correctly, since Claude Code tells Claude explicitly not to retry a request nobody can approve. If you're seeing repeated attempts, confirm you passed --permission-prompts none rather than leaving it at the host default, and check whether a PermissionRequest hook is intermittently allowing then re-denying the same call.

A run finishes with work missing and no obvious error. Re-run with --output-format stream-json and inspect the permission_denials list in the result message. That tells you exactly which actions were denied for lack of a human to ask, which is usually the fastest way to see whether your permission mode or allow rules need adjusting rather than the flag itself.

I want some requests answered and others denied automatically. --permission-prompts none is all-or-nothing for the "nobody's here" case. For finer control, configure a PermissionRequest hook that allows specific requests programmatically; anything the hook doesn't resolve still falls through to the flag's denial behaviour.

This isn't the same problem as --dangerously-skip-permissions. If your actual goal is to skip permission checks entirely rather than deny the ones that would have needed a human, you want bypassPermissions, and Claude Code's own guidance is that it belongs only in isolated containers and VMs. --permission-prompts none doesn't widen what Claude can do; it only changes what happens to the requests that were already going to be refused.

Where this fits with the rest of Claude Code's automation story

--permission-prompts none is a small, single-purpose flag, but it closes a real gap in running Claude Code unattended: previously, the only way to guarantee a headless run wouldn't hang was to make sure absolutely nothing in a task could ever need human input, which is hard to promise for anything nontrivial. Now a scheduled job, a CI step, or a self-hosted runner can combine a sensible permission mode with this flag and get a predictable outcome every time: either the task completes, or it comes back with a clear, structured record of exactly what it couldn't do without you. For the wider picture of how Claude Code decides what to auto-approve in the first place, see auto mode's classifier rules, and for everything else the CLI supports, browse Claude Code's platform page.

Frequently asked questions