← NEWS DESK
release impact

Three OpenClaw Merges Close Silent Data-Loss Paths in Sessions and Delivery Queues

A pruning inversion deleted eligible sessions, an ingress watchdog dead-letted timed-out Telegram messages with attempts=0, and recovery erased queued deliveries during transient adapter outages — all three are fixed on main.

Independent reporting and tested guidance for OpenClaw operators · Editorial standards

Three reliability repairs merged to main on August 21, 2026 share one signature: the system reported success or silence while destroying operator data. None requires configuration changes; all three change what you should assume about pre-fix instances.

Session history silently deleted when pruning was disabled

PR #127277 fixes a maintenance-owner bug where a plugin disabling age-based session pruning with a non-positive retention value caused every inactive eligible session to be silently deleted during an entry patch. The owner treated retention as cutoff arithmetic without first handling its disabled state.

The fix returns before mutation for non-positive retention, and the SQLite preflight skips its stale-row scan and full-store load in that case. Positive-retention behavior is unchanged. Upstream evidence includes a red-on-main regression (a pruneAfterMs: 0 fixture expected a session to survive; it received undefined), 90 passing grouped tests covering positive/zero/negative cases through the public Plugin SDK into SQLite, and a live Telegram end-to-end proof showing removedKeys: [].

Operator action: if any installed plugin sets age retention to zero or negative, audit whether sessions disappeared while it ran. Upgrades restore correct behavior but not deleted history — check your SQLite backups for affected windows.

Timed-out inbound messages were marked failed before their first attempt

PR #127090 closes issue #126231: a durable channel message exceeding the claim-to-adoption watchdog was immediately terminal-failed as handler-timeout with attempts=0. On Telegram this meant users could watch their message reach the bot while OpenClaw silently dropped it.

Two secondary traps are also closed: a late first attempt that ignored cancellation could commit process-local dedupe before durable adoption (consuming the replay), and an aborted Telegram spool participant could return a false completed result.

The drain now routes watchdog timeouts through the existing retry disposition instead of bypassing it with a direct dead-letter write, preserving the claim-token fence and settle-once ownership. Later messages on the same lane stay behind the retried message; terminal failure still follows the normal attempt and minimum-age policy. No operator configuration is needed.

Operator action: if you run Telegram (or another durable channel) on a pre-fix build and cannot account for a user report of a missing message, re-check spool records after upgrading rather than assuming the report was user error. The fix’s own regression demonstrated all three failure points reproducing on origin/main before repair.

Transient adapter outages erased queued outbound deliveries

PR #126800 removes /outbound not configured for channel from the permanent-error list in delivery queue recovery. That error string is produced by local adapter resolution — which can fail transiently when bootstrap registry loading fails and caches a negative outcome for the generation — yet recovery treated it like a permanent provider rejection: it moved the pending row to failed at attempt zero, deleted the payload per the post-#123642 no-payload policy, and unlinked spooled attachments.

The same condition was already classified retryable on the live send path, so recovery was strictly more destructive than dispatch. The PR documents recurring occurrences on stock config across qqbot (~every 30 minutes), Discord, and Telegram issues.

After the fix, adapter unavailability consumes the normal retry budget (default five attempts); genuinely gone channels still terminate via the existing exhaustion branch, so this introduces no unbounded loop. The sibling lists for in-process announce and cron dispatch were deliberately left unchanged because their failure mode reports instead of deleting custody copies.

Operator action: if you operate qqbot, Discord, or Telegram queues on affected builds, treat historical empty failures with attemptCount stuck at zero around gateway restarts as likely casualties of this bug, not provider rejections. Verify your retry budget assumptions on upgrade.

Why these three belong together

Each bug converted a safety mechanism — pruning bounds, watchdog discipline, permanent-vs-retryable classification — into a destruction trigger by mishandling one edge case: the disabled state, the timeout boundary, and the local-vs-provider error class. The common lesson for operators is that “it failed cleanly” and “it failed destructively” are different claims requiring different evidence. After upgrading, verify from spool rows and store contents rather than logs alone.

THE RECEIPTS

Claims should survive the click.

Primary links used for this article are listed openly. If the evidence changes, the verification date changes with it.
  1. 01fix(sessions): preserve sessions when age pruning is disabled — PR #127277
  2. 02fix(channels): retry timed-out ingress messages — PR #127090
  3. 03fix(outbound): retry queued deliveries when a channel adapter is unavailable — PR #126800

THE OPERATOR BRIEF

One useful email when the signal earns it.

Release impact, security changes and repository intelligence. No daily sludge.