-
-
Notifications
You must be signed in to change notification settings - Fork 62.6k
Closed
Description
Summary
Isolated agentTurn cron jobs deadlock on the cron lane when cron.maxConcurrentRuns is 1 (the default). Sessions get created in sessions.json but the LLM call never fires — transcript files are 0 bytes/missing, and jobs always hit their timeout.
Version / OS
- OpenClaw: 2026.3.8 (stable)
- OS: macOS 15.6 (arm64)
- Node: v24.13.0
Repro (minimal)
cron.maxConcurrentRunsat default (1), or explicitly set to 1- Create any isolated cron with
payload.kind: "agentTurn":{ "sessionTarget": "isolated", "payload": { "kind": "agentTurn", "message": "Reply: OK", "timeoutSeconds": 60 } } - Trigger via
openclaw cron run <jobId>or wait for schedule - Observe:
- Session entry created in
sessions.json✅ - Transcript
.jsonlfile missing or 0 bytes ❌ - Job times out ❌
- Gateway logs show
lane wait exceeded: lane=cron waitedMs=32586 queueAhead=0
- Session entry created in
Root cause
The cron runner queues work on the cron lane. The isolated agent turn (runEmbeddedPiAgent) is also invoked with lane: "cron". With maxConcurrentRuns: 1:
- Cron runner takes slot 1 on the cron lane
- Embedded agent run queues behind it on the same lane
- Agent run cannot start — only 1 slot available
- Cron runner cannot finish — waiting for agent run
- Deadlock until timeout kills everything
Workaround
Set cron.maxConcurrentRuns: 2 and restart:
// ~/.openclaw/openclaw.json
{
"cron": {
"maxConcurrentRuns": 2
}
}openclaw gateway restartAfter this, the same canary cron completes in 4.6 seconds.
Affects
- All embedded providers tested: Anthropic (claude-opus-4-6, claude-sonnet-4-6), GLM (glm-4.7)
- Multiple agents tested: custom agents + main agent
- Sub-agents spawned from live chat sessions work perfectly (same models, same tasks)
- Only cron-initiated isolated sessions are affected
Log snippet
[diagnostic] lane wait exceeded: lane=cron waitedMs=32586 queueAhead=0
Suggestion
The cron isolated agent runner should not enqueue the embedded run onto the same cron lane the cron service is executing on. Options:
- Use a distinct lane name for the embedded run (e.g.
cron-agent) - Avoid lane nesting entirely
- Or at minimum, set the default
maxConcurrentRunsto 2+ so the default config works out of the box
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Type
Fields
Give feedbackNo fields configured for issues without a type.