Desktop: scheduled task permission mode doesn't persist (reverts to default), so unattended routines stall on approval prompts
Status Open
Maintainer reply None cached
Workaround ✓ Mentioned in description ↑
Activity 1 comment · opened Oct 12, 2026
Summary
In the Claude desktop app (Code tab), a scheduled task's permission mode does not stick. I set a routine to Bypass permissions (or Auto) and it keeps reverting to the default ("manual"), so unattended runs block on approval prompts. This combines badly with the rule that writes under ~/.claude always ask outside bypass: every run of the routine stalls on its first step until a human clicks Approve. In my case runs sat for about 30 hours.
Environment
- Claude desktop app 2.31226.1, macOS (Darwin 24.6)
- Local scheduled tasks created with the
scheduled-tasksMCP tools (create_scheduled_task), cwd = a git repo
Steps to reproduce
- Create a recurring local scheduled task whose prompt writes a file under
~/.claude/..., for exampledate > ~/.claude/some-dir/x.txt. - In the Code tab, set the routine's permission mode to Bypass permissions.
- Wait for a few scheduled fires, or for the task to record
per_task_limitskips while a previous run is still active. - Look at the routine again, and at
~/Library/Application Support/Claude/claude-code-sessions/<account>/<org>/scheduled-tasks.json.
Expected
The routine keeps the chosen mode, and every run starts in Bypass.
Actual
- The routine shows the default mode again; the user has to re-select Bypass repeatedly.
scheduled-tasks.jsonhas nopermissionModefield for these tasks. A task created months ago through the UI does have"permissionMode": "bypassPermissions".- Runs start in
defaultorauto(seen in the per-session JSON as"permissionMode": "default"/"auto"with"autoChosenInApp": true), and each blocks on its first write under~/.claudeuntil someone approves. From the session transcripts: a 28.5 h gap and a 31 h gap between the firsttool_useand its result. - The file's last write matched, to the second, a
recordedSkipsentry (reason: "per_task_limit"). These skips are written about once a minute while a run is active (more than 1,300 entries for one task). My suspicion is that a whole-file rewrite from a stale in-memory copy drops the field. I have not confirmed this. - Related: disabling a task via
update_scheduled_task(enabled: false) was later found re-enabled without anyone touching it, which also points to a stale-copy overwrite.
Also
- A scheduled routine that calls
ccd_session_mgmt__set_session_efforton another session always gets an "Allow once"-only prompt ("In a session started by a schedule … Claude always asks"), so it can never run unattended. That may be by design, but there is then no way to give scheduled runsmaxeffort: task frontmatter only acceptsmodel, andmaxcannot be persisted. - Scheduled runs inherit
mediumeffort unlesseffortLevelis set in settings.
Workaround
- Keep routine state outside
~/.claude. - Add a
permissions.allowlist plusadditionalDirectoriesto the project's.claude/settings.local.json, so runs no longer depend on the routine's permission mode. - Set
"effortLevel": "xhigh"there.
With that in place, a test routine ran all steps unattended.
Possibly related: #97875
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗