Skip to content

FailoverError during cli-backend turn does not clear stale cliSessionIds from sessions.json, causing infinite retry loop #97887

Description

@riazrahaman

Summary

When a claude-cli turn fails with FailoverError (e.g. because the session file no longer exists after a gateway restart), the stale CLI session ID is not removed from sessions.json. Every subsequent message on that conversation then retries the dead session ID and fails again with ⚠️ Something went wrong while processing your request. — an infinite failure loop with no self-healing.

Steps to Reproduce

  1. Have an active Telegram (or other inbound channel) session using claude-cli backend.
  2. Restart the openclaw gateway (e.g. openclaw gateway restart). This creates a new claude CLI process; the old ~/.claude/sessions/<uuid>.jsonl session file is orphaned but the session ID stays persisted in sessions.json.
  3. Send a message in Telegram. openclaw tries to resume the stale session ID (useResume=true), the claude CLI reports Not logged in · Please run /login, which causes a FailoverError.
  4. openclaw delivers GENERIC_EXTERNAL_RUN_FAILURE_TEXT and logs claude live session close: reason=restart.
  5. Bug: sessions.json still contains the stale session ID. Sending another message triggers the exact same failure.

Root Cause

In agent-runner.runtime-C8N-o26U.js, the clearCliSessionBinding flag is set from runResult.meta?.agentMeta?.clearCliSessionBinding (line ~3361). This field is only populated from a successful run result — it is undefined on a FailoverError path. Consequently, clearCliSession(nextEntry, cliProvider) is never called, and updateSessionEntry is never called with the cleared cliSessionIds/cliSessionBindings.

The persisted sessions.json structure:

"agent:main:telegram:direct:<userId>": {
  "cliSessionIds": { "claude-cli": "<stale-uuid>" },
  "cliSessionBindings": { "claude-cli": { "sessionId": "<stale-uuid>", ... } },
  "claudeCliSessionId": "<stale-uuid>"
}

All three fields survive the restart and point to a non-existent ~/.claude/sessions/<stale-uuid>.jsonl.

Expected Behaviour

When a FailoverError (or any error indicating the CLI session is gone) occurs during a claude-cli backend turn, openclaw should:

  1. Call clearCliSession(entry, cliProvider) on the active session entry.
  2. Persist the cleared state to sessions.json via updateSessionEntry.

This ensures the next message starts a fresh claude-cli session instead of re-attempting the dead one.

The error-recovery path in agent-runner.runtime-C8N-o26U.js that delivers GENERIC_EXTERNAL_RUN_FAILURE_TEXT should include this cleanup step, analogous to how clearCliSessionBinding: true works for the success path.

Workaround

Manually patch sessions.json and restart the gateway:

python3 -c "
import json
path = '/path/to/.openclaw/agents/main/sessions/sessions.json'
data = json.load(open(path))
entry = data.get('agent:main:telegram:direct:<userId>', {})
for field in ['cliSessionIds', 'cliSessionBindings', 'claudeCliSessionId']:
    entry.pop(field, None)
open(path, 'w').write(json.dumps(data, indent=2))
"
openclaw gateway restart

Affected Scenario

This is triggered by two rapid openclaw gateway restart calls (e.g. openclaw config set + manual restart), which invalidates the in-memory live session and creates a new gateway PID. The stale session ID survives in sessions.json but the corresponding session file does not.

Environment

  • openclaw version: 2026.6.10
  • Platform: macOS (darwin)
  • Backend: claude-cli
  • Channel: Telegram (likely affects all inbound channels using the cli backend)

Related: #97553 (the "Not logged in" error not matching isOAuthRefreshFailureMessage, causing generic error text instead of a specific message)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.no-staleExclude from stale automation

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions