[BUG] Scheduled routines (CCR) hang indefinitely after set_permission_mode handshake, never execute task

Status Open
Maintainer reply None cached
Activity 1 comment · opened Sep 25, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Scheduled cloud routines (CCR) created via the routines API hang indefinitely and never execute their task.

The routine fires correctly on schedule (or via manual "run"), allocates a sandbox, and starts Claude Code. The session log shows a control_request/set_permission_mode event followed by a control_response, and then nothing else ever happens — no tool calls, no assistant turns, no output. The trigger's last_run.status stays ROUTINE_RUN_STATUS_PENDING and the session's worker_status stays idle indefinitely (observed for over an hour on one run).

This reproduces across multiple, unrelated routines with different configs:

  • A Slack digest routine using a Slack MCP connector with default tool access (Bash, Read, etc.)
  • The same routine rebuilt from scratch (new trigger, same prompt) — same hang, ruling out a one-off config issue
  • A pre-existing, unrelated routine (Confluence/Jira refresh) using only an Atlassian MCP connector with most built-in tools disallowed

Example session IDs showing the hang:

  • cse_01S8VrVaByZ3GWU3i9sLE529 (natural cron fire)
  • cse_01Mer64pbUgkMca8bUu6P64V (manual re-run of the same routine)
  • cse_01EGzM1xJVZ83b63rh2ZTn8r (manual run on a freshly recreated routine)
  • Also seen on trigger trig_0125xAAdeHQyba3RezagvijS (unrelated routine, different config)

I also tried setting job_config.ccr.session_context.permission_mode via the update API to bypass this, but the field is silently dropped (not part of the accepted schema), so there's no client-side workaround available.

What Should Happen?

The scheduled routine should proceed past the permission-mode handshake automatically (since these are unattended runs with no user available to respond to prompts) and actually execute the task: call its tools (Bash, MCP connectors, etc.), complete the work described in its prompt, and report success/failure — rather than hanging indefinitely in a PENDING/idle state.

Error Messages/Logs

Run log from GET /v1/code/sessions/{session_id}/events (via the RemoteTrigger get_run_log equivalent), 12 events total, 7 shown as transcript, 5 filtered as non-transcript control events. Identical pattern on every affected run:

[env/info]: Allocating sandbox
[env/info]: Launching Claude Code from /opt/claude-code/bin/claude (mount)
[env/info]: Environment runner started
[env/info]: No sources configured
[env/info]: No setup script configured
[env/info]: Starting Claude Code
[env/info]: Claude Code process started

Non-transcript events present but not expanded by the API: control_response x1, autocompact_state x1, active_goal x1, system/turn_handoff_available x1, control_request/set_permission_mode x1.

No events beyond this point were ever emitted — checked repeatedly over 1+ hour on one run (cse_01S8VrVaByZ3GWU3i9sLE529) with no change. No tool_use, no assistant message, no error, no completion event.

Trigger-level state after the fact:
"last_run": {"failure_reason": "ROUTINE_RUN_FAILURE_REASON_UNSPECIFIED", "status": "ROUTINE_RUN_STATUS_PENDING"}

Steps to Reproduce

  1. Create a scheduled routine via POST /v1/code/triggers with a job_config.ccr body, e.g.:

{
"name": "Test Routine",
"cron_expression": "0 18 1-5",
"enabled": true,
"job_config": {
"ccr": {
"environment_id": "<any environment_id, e.g. the account's Default environment>",
"session_context": {
"model": "claude-sonnet-5",
"events": [{
"data": {
"uuid": "<a fresh lowercase v4 uuid>",
"session_id": "",
"type": "user",
"parent_tool_use_id": null,
"message": {"role": "user", "content": "Run date and reply with the current time."}
}
}]
}
}
}
}

  1. Trigger it immediately with POST /v1/code/triggers/{trigger_id}/run (no need to wait for the cron).
  1. Poll GET /v1/code/sessions/{trigger_id}/events (or list_runs -> get_run_log) for the returned session_id.
  1. Observe: the log reaches exactly 12 events (sandbox allocation + Claude Code startup + a control_request/set_permission_mode / control_response pair) and then stops permanently. No tool call for the trivial date command ever appears, no assistant reply, no terminal/completion status — even after waiting significantly longer than the trivial task should take.
  1. This reproduces on a brand-new routine created from scratch (not just a stale/misconfigured one) — confirmed by deleting the reproduction down to a fresh trigger with a minimal prompt and re-running step 2-4.
  1. Also confirmed on a second, pre-existing routine in the same account with an entirely different tool/connector configuration (Atlassian MCP connector, most built-in tools disallowed) — same stuck point.

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

N/A — this bug is in cloud-hosted scheduled routines (CCR), not a local Claude Code CLI session. No local CLI was involved in reproducing this.

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

This bug does not involve a local terminal/CLI session — it's entirely server-side, in Claude's scheduled cloud routines (CCR) feature, accessed via the routines API (POST/GET /v1/code/triggers, /v1/code/sessions).

Relevant trigger/session IDs for reference:

  • trig_01MT2yNtiHfZ1HRAdCAcHu9h — "Slack Digest - Noon (Weekdays)" — stuck on both its natural cron fire and a manual re-run
  • trig_01EEfuEF6v5GBJS4ZigSZSgS — freshly recreated duplicate of the above, created purely to rule out a config/state issue — same hang on first run, now disabled
  • trig_0125xAAdeHQyba3RezagvijS — pre-existing, unrelated routine ("COM Compliance Dashboard - Hourly Refresh v2") with a completely different prompt/tool/connector setup — same stuck PENDING/idle state observed

All three routines use the same "Default" environment (env_015HqeRxpJqMx1msUyCcpLxM). Willing to share full job_config JSON or grant access to the account for debugging if useful — just ask.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗