openclaw - ✅(Solved) Fix Feature: `openclaw logs --follow` should auto-reconnect instead of exiting on transient gateway disconnect [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#74782Fetched 2026-05-01 05:41:23
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
2
Author
Timeline (top)
commented ×1cross-referenced ×1mentioned ×1subscribed ×1

Error Message

The only fallback path is shouldUseLocalLogsFallback(), which only triggers for pairing-required messages (readConnectPairingRequiredMessage). All other errors (connection refused, network error, WebSocket close, etc.) are treated as fatal. 3. Observe: openclaw logs --follow exits with gateway connect failed error instead of reconnecting

Root Cause

Looking at logs-cli.ts (v2026.4.26, logs-cli-BwVDUQL4.js), the fetch loop in logs --follow works as a polling loop calling callGatewayFromCli("logs.tail"):

while (true) {
  try {
    payload = await fetchLogs(opts, cursor, showProgress);
  } catch (err) {
    await emitGatewayError(err, opts, jsonMode ? "json" : "text", rich, emitJsonLine, errorLine);
    process.exit(1);  // ← exits immediately, no retry
    return;
  }
  // ... process lines ...
  await setTimeout(interval);
}

The only fallback path is shouldUseLocalLogsFallback(), which only triggers for pairing-required messages (readConnectPairingRequiredMessage). All other errors (connection refused, network error, WebSocket close, etc.) are treated as fatal.

Fix Action

Fixed

PR fix notes

PR #75059: fix(cli): auto-reconnect logs --follow on transient gateway disconnect #74782

Description (problem / solution / changelog)

Closes #74782

What this fixes

openclaw logs --follow exits immediately on any gateway error — including a simple gateway restart — forcing the user to manually re-run the command.

Before:

$ openclaw logs --follow
... logs streaming ...
[gateway restarts]
Gateway not reachable. Is it running and accessible?
$   ← dead, user re-runs manually

After:

$ openclaw logs --follow --url ws://127.0.0.1:18789
... logs streaming ...
[gateway restarts]
[logs] gateway disconnected, reconnecting in 1s...
[logs] gateway disconnected, reconnecting in 2s...
... logs resume ...

How it works

The --follow polling loop now retries on transient transport failures instead of calling process.exit(1). Backoff: 1 s → 2 s → 4 s → … → 30 s cap, up to 8 attempts. The retry counter resets after every successful fetch.

Not everything is retried — non-recoverable errors exit immediately:

  • Close code 1008 (policy violation / pairing required)
  • Close code 4000–4999 (auth, rate-limit)
  • Any error that is not a transport-level disconnect

Scope

This adds explicit retry for --url targets. For implicit loopback connections the existing local-file fallback already prevents exit — that path is preserved as-is.

Verified

pnpm test src/cli/logs-cli.test.ts                                              # 21/21
pnpm exec oxfmt --check --threads=1 src/cli/logs-cli.ts src/cli/logs-cli.test.ts  # clean

Changed files

  • docs/cli/logs.md (modified, +1/-0)
  • src/cli/logs-cli.test.ts (modified, +145/-0)
  • src/cli/logs-cli.ts (modified, +43/-0)

Code Example

while (true) {
  try {
    payload = await fetchLogs(opts, cursor, showProgress);
  } catch (err) {
    await emitGatewayError(err, opts, jsonMode ? "json" : "text", rich, emitJsonLine, errorLine);
    process.exit(1);  // ← exits immediately, no retry
    return;
  }
  // ... process lines ...
  await setTimeout(interval);
}
RAW_BUFFERClick to expand / collapse

Problem

When running openclaw logs --follow, any transient gateway WebSocket disconnect (e.g., gateway restart, temporary connection drop) causes the CLI to immediately process.exit(1), terminating the log tail session.

This is particularly annoying during gateway restarts or when brief connectivity hiccups occur — the user has to manually re-run the command.

Root Cause Analysis

Looking at logs-cli.ts (v2026.4.26, logs-cli-BwVDUQL4.js), the fetch loop in logs --follow works as a polling loop calling callGatewayFromCli("logs.tail"):

while (true) {
  try {
    payload = await fetchLogs(opts, cursor, showProgress);
  } catch (err) {
    await emitGatewayError(err, opts, jsonMode ? "json" : "text", rich, emitJsonLine, errorLine);
    process.exit(1);  // ← exits immediately, no retry
    return;
  }
  // ... process lines ...
  await setTimeout(interval);
}

The only fallback path is shouldUseLocalLogsFallback(), which only triggers for pairing-required messages (readConnectPairingRequiredMessage). All other errors (connection refused, network error, WebSocket close, etc.) are treated as fatal.

Expected Behavior

openclaw logs --follow should:

  1. Auto-reconnect on transient errors (connection refused, network unreachable, WebSocket closed)
  2. Log a warning about the disconnect (e.g., [logs] gateway disconnected, reconnecting...)
  3. Retry with exponential backoff (similar to the gateway client reconnect logic)
  4. Only exit on non-recoverable errors (auth failure, wrong URL, etc.)
  5. Optionally support --max-retries or --retry-interval flags

Reproduction

  1. Run openclaw logs --follow in one terminal
  2. Restart the gateway: openclaw gateway restart
  3. Observe: openclaw logs --follow exits with gateway connect failed error instead of reconnecting

Environment

  • OpenClaw version: 2026.4.26 (be8c246)
  • OS: Linux 6.16.4
  • Gateway bind: loopback (127.0.0.1:18789)

Related

The gateway client already has sophisticated reconnect/backoff logic (seen in client-Dh94CUDv.js), but the CLI logs command does not reuse or replicate it.

extent analysis

TL;DR

Modify the logs-cli.ts to implement retry logic with exponential backoff for transient gateway WebSocket disconnects.

Guidance

  • Identify and handle specific error types (e.g., connection refused, network error, WebSocket close) to trigger retry logic instead of immediate exit.
  • Implement exponential backoff for retries, similar to the gateway client reconnect logic in client-Dh94CUDv.js.
  • Log a warning message when a disconnect occurs and the CLI is attempting to reconnect.
  • Consider adding optional flags (--max-retries, --retry-interval) to allow users to customize retry behavior.

Example

const maxRetries = 5;
const initialRetryInterval = 1000; // 1 second
let retryCount = 0;

while (true) {
  try {
    payload = await fetchLogs(opts, cursor, showProgress);
  } catch (err) {
    if (retryCount < maxRetries && isTransientError(err)) {
      console.warn(`[logs] gateway disconnected, reconnecting... (attempt ${retryCount + 1}/${maxRetries})`);
      await setTimeout(initialRetryInterval * (2 ** retryCount));
      retryCount++;
    } else {
      await emitGatewayError(err, opts, jsonMode ? "json" : "text", rich, emitJsonLine, errorLine);
      process.exit(1);
    }
  }
  // ... process lines ...
  await setTimeout(interval);
  retryCount = 0; // reset retry count on successful fetch
}

function isTransientError(err) {
  // implement logic to check if error is transient (e.g., connection refused, network error, WebSocket close)
}

Notes

The provided example is a simplified illustration and may require adjustments to fit the specific requirements of the logs-cli.ts implementation.

Recommendation

Apply workaround by modifying the logs-cli.ts to implement retry logic with exponential back

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix Feature: `openclaw logs --follow` should auto-reconnect instead of exiting on transient gateway disconnect [1 pull requests, 1 comments, 2 participants]