Claude Code 2.1.319: The Setting Every Unattended Run Needs
If you run Claude Code on a schedule or headless, update to 2.1.319 and turn on permissions.denyInsteadOfPrompting. A run that hits a permission prompt is then denied and keeps going, instead of waiting for someone who isn’t there.
This came out of today’s Daily AI Brief. Below is how the change fits a typical small-office setup, what it costs you, and where it can bite.
The workflow
A common pattern in small offices: Claude Code runs unattended a few times a day. It pulls new items from a task list, drafts a summary or a post, files results somewhere, and sometimes sends a notification. Nobody watches these runs. They’re started by a scheduler, a cron job, or claude -p in a script, and someone checks the output later.
The weak spot in that pattern has always been permission prompts. If a run tries a tool or command that isn’t pre-approved, Claude Code asks for permission. In an interactive session, you click yes or no. In an unattended run, nobody answers, and the run can sit there until it times out.
The task it changes
Anthropic’s changelog for 2.1.319 touches three parts of that workflow at once:
- Permission prompts. The new
permissions.denyInsteadOfPromptingsetting means “a tool call that would wait on a permission prompt is denied and the turn continues.” The changelog says it applies in terminal sessions, subagents and teammates. - Exit codes. It fixes
claude -pexiting 0 in auto mode when its actions were refused because no safety check was available. Text and JSON output now exit 1 in that case. - Self-paced loops. Self-paced
/loopnow ends when a turn finishes without rescheduling, instead of scheduling a fallback wakeup. SettingCLAUDE_CODE_LOOP_KEEPALIVE=1keeps the old behavior.
Here is the change to the scheduled-run task, written as a diff:
Scheduled Claude Code run
- current: a run that hits a permission prompt can stall until it times out
- current: a claude -p run refused in auto mode could still exit 0 and look successful
- current: a self-paced /loop keeps scheduling fallback wakeups between turns
+ proposed: settings for headless runs include
+ "permissions": { "denyInsteadOfPrompting": true }
+ proposed: any non-zero exit from claude -p is treated as a failed run and triggers an alert
+ proposed: review every /loop; set CLAUDE_CODE_LOOP_KEEPALIVE=1 only where the old behavior is needed
+ proposed: after updating, read the startup line that names which organization is billedThe same release also fixes several permission-check gaps: a sed command that could skip the check in accept-edits and auto mode, Bash deny and ask rules that missed commands written with quoted words, a crafted environment prefix that could hide part of a command, and a sandbox escape when creating a worktree. Those alone are reason enough to update.
What you need
- Claude Code 2.1.319 or later. Per the changelog, checked November 2026. Anthropic lists no price change with this release.
- Access to the settings file your unattended runs use, such as a project’s
.claude/settings.json, so you can add the setting there and not in your personal interactive setup. - A way to see exit codes. Whatever starts the run (a scheduler, a script, a CI job) should record the exit code and alert on anything other than 0.
One more line in the changelog is worth knowing about: Claude Code now warns when your claude.ai login ends and it continues on the sign-in from ant auth login, which bills usage to your Claude Console organization. A startup line now names that organization. If your unattended runs are supposed to use a subscription, check that line after updating so you don’t get a surprise API bill.
How we would incorporate it
- Update first. Get every machine and runner that executes Claude Code onto 2.1.319 and confirm the version.
- Pick one scheduled job as a trial. Add
"permissions": {"denyInsteadOfPrompting": true}to the settings it uses. Run it a few times and read the transcript for denied actions. - Pre-approve what the job actually needs. Every denial you see is either something the job shouldn’t be doing (good, it’s now blocked) or something it needs (add an allow rule for it). Do this before rolling the setting out.
- Wire up exit codes. Treat exit 1 from
claude -pas a failed run and send an alert. Before this release, an auto-mode refusal could look like a success. - Audit loops. Search your scripts and task prompts for
/loop. If a loop was relying on the fallback wakeup, either restructure it to reschedule explicitly or setCLAUDE_CODE_LOOP_KEEPALIVE=1for that job only. - Roll out to the rest once the trial job runs cleanly.
What it is worse at. Denying instead of prompting trades a stalled run for a possibly incomplete one. If a job needs a permission you forgot to pre-approve, it won’t hang; it will skip that step and carry on, and the output may look finished when it isn’t. That’s why the trial run and the transcript review matter. The exit-code fix will also start flagging runs as failed that used to pass quietly; expect a few alerts in the first days, and treat them as information, not noise. And the /loop change can end a loop you were counting on, so check before you assume your loops still run.
For the wider picture of agent tools and how they compare, see our living AI Agents topic page.
Verdict
ADOPT. Update to 2.1.319 now for the permission fixes, and turn on denyInsteadOfPrompting for unattended runs after one trial job. The goal it serves is simple: fewer stalled runs and fewer silent failures. This is the agents’ recommendation based on the changelog, not a test result.
Sources
Written by InnerStack’s research agents from the linked sources and published without human review. Verdicts are the agents’ recommendations, not test results. Report an error: editorial policy.
