| name | diagnose-lifecycle-worker |
| description | Diagnose and fix AO lifecycle-worker backfill failures (stale worktrees, branch conflicts, claim_failed loops) |
Lifecycle-Worker Diagnostic Skill
Use this when lifecycle.backfill.claim_failed errors appear in lifecycle-worker logs, or when open PRs have no active sessions and are stalling.
Step 1 — Confirm lifecycle-worker is running
pgrep -af "lifecycle-worker"
If nothing: lifecycle-worker is not running. Check launchd state:
launchctl print gui/$(id -u)/com.agentorchestrator.lifecycle-agent-orchestrator 2>&1 | grep "state ="
If state ≠ running, bootstrap it:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.agentorchestrator.lifecycle-agent-orchestrator.plist
Step 2 — Find the lifecycle log
ls ~/.openclaw/logs/ao-lifecycle-*.log 2>/dev/null | tail -5
ls ~/.agent-orchestrator/*/logs/lifecycle-*.log 2>/dev/null | tail -5
Tail the most recent log:
tail -50 ~/.openclaw/logs/ao-lifecycle-<project>.log
Step 3 — Find claim_failed errors
grep -n "claim_failed\|refusing to fetch\|Session not found" ~/.openclaw/logs/ao-lifecycle-<project>.log | tail -20
Extract the error message and branch/worktree path from the output.
Step 4 — Triage by error type
Path A: "refusing to fetch into branch" (ghost worktree)
This means a worktree has a branch checked out that the lifecycle-worker is trying to fetch into.
Identify the worktree and branch:
Check if the worktree's tmux session is alive:
tmux has-session -t <session-name> 2>/dev/null && echo "ALIVE" || echo "DEAD"
If dead — remove the ghost worktree:
WORKTREE="/path/to/worktree"
GIT_DIR="$(dirname "$WORKTREE")"
git -C "$GIT_DIR" worktree remove --force "$WORKTREE"
git -C "$GIT_DIR" branch -d <branch-name>
git -C "$GIT_DIR" branch -D <branch-name>
Verify the fix works:
GIT_DIR="$(dirname "/path/to/worktree")"
git -C "$GIT_DIR" fetch --force origin +refs/pull/<PR_NUMBER>/head:<branch-name>
Path B: "Session not found" (orphaned session metadata)
The lifecycle-worker lost track of a session.
Identify the repo from the log context (look for project: in the lifecycle log):
grep -n "project:" ~/.openclaw/logs/ao-lifecycle-<project>.log | tail -5
Find orphaned session metadata:
ls ~/.agent-orchestrator/*/sessions/archive/ 2>/dev/null | head -20
ls ~/.agent-orchestrator/*/sessions/ 2>/dev/null | head -20
Find orphaned worktrees — always scope to the correct worktreeDir:
python3 -c "
import yaml
cfg = yaml.safe_load(open('$HOME/.openclaw/agent-orchestrator.yaml'))
proj = cfg['projects']['<project-name>']
print('worktreeDir:', proj.get('worktreeDir', '~/.worktrees/' + proj.get('name','').lower().replace(' ', '-')))
print('repo:', proj.get('repo'))
"
WORKTREE_DIR="~/.worktrees/jleechanclaw-main"
git -C "$WORKTREE_DIR" worktree list
Find orphaned worktrees:
git worktree list | grep <project-name>
If you find a worktree with no corresponding live tmux session, it's orphaned — remove it per Path A.
Path C: Wrong branch checked out in main repo
If the error path points to the main repo (not a worktree):
git -C /path/to/repo branch --show-current
If it's not main:
git -C /path/to/repo checkout main && git -C /path/to/repo pull --ff-only
Step 5 — Verify lifecycle-worker resumes
tail -f ~/.openclaw/logs/ao-lifecycle-<project>.log
Look for new entries — the lifecycle-worker should resume processing within a few minutes.
Step 6 — Escalation (3+ consecutive failures)
If the same PR has failed 3+ times after cleanup, something systemic is wrong.
Send MCP mail alert:
Use the MCP mail tool (or mcp__mcp-agent-mail__send_message):
project_key: "jleechanclaw" (or relevant project)
sender_name: "claude"
subject: "lw-stall: PR #"
body_md: "3+ consecutive claim_failed for PR # on after cleanup attempts. Manual intervention required. Last error: <error snippet>"
Alternatively via curl:
OPENCLAW_SLACK_BOT_TOKEN="${OPENCLAW_SLACK_BOT_TOKEN:-}"
JLEECHAN_DM_CHANNEL="${JLEECHAN_DM_CHANNEL:-}"
curl -s -X POST "https://slack.com/api/chat.postMessage" \
-H "Authorization: Bearer ${OPENCLAW_SLACK_BOT_TOKEN:-$SLACK_USER_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"channel\": \"${JLEECHAN_DM_CHANNEL:-C0AKALZ4CKW}\", \"text\": \"*[AO Alert]* lifecycle-worker stalled on <project> PR #<N>. 3+ consecutive failures. Manual intervention required.\"}"
Quick Reference: Common Error → Fix Map
| Error substring | Likely cause | Fix |
|---|
refusing to fetch into branch + worktree path | Ghost worktree | git worktree remove --force <path> |
refusing to fetch + main repo path | Main repo on wrong branch | git checkout main && git pull |
Session not found | Orphaned session metadata | Find+remove orphaned worktrees |
already exists on worktree add | Duplicate worktree | git worktree remove --force <path> then retry |
| Rate limit | gh API exhausted | Wait ~1hr; check gh api rate_limit |