Skip to content

fix: log terminal session persistence failures#97839

Merged
steipete merged 3 commits into
openclaw:mainfrom
LZY3538:codex/log-chat-abort-persistence
Jul 3, 2026
Merged

fix: log terminal session persistence failures#97839
steipete merged 3 commits into
openclaw:mainfrom
LZY3538:codex/log-chat-abort-persistence

Conversation

@LZY3538

@LZY3538 LZY3538 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Fixes #97795

What Problem This Solves

Fixes an issue where operators would not see any diagnostic output when a terminal session lifecycle persistence write failed during gateway run completion. The gateway still broadcast a fallback terminal snapshot, but the persistence failure itself was silent.

Why This Change Was Made

The terminal lifecycle persistence failure path now logs the rejected write at the gateway event handling boundary before preserving the existing fallback broadcast behavior. The rejection is formatted through the existing gateway formatForLog(err) helper so arbitrary error text is redacted and capped before it reaches operator-visible logs.

User Impact

Operators get an actionable gateway error log when terminal session persistence fails, making session-state storage problems easier to diagnose without changing normal chat or abort behavior.

Evidence

RED: node scripts/run-vitest.mjs run --config test/vitest/vitest.gateway.config.ts src/gateway/server-chat.agent-events.test.ts failed before the implementation because logError was not called.

GREEN:

node scripts/run-vitest.mjs run --config test/vitest/vitest.gateway.config.ts src/gateway/server-chat.agent-events.test.ts
Test Files  1 passed (1)
Tests  99 passed (99)

Focused related proof after the formatter update:

node scripts/run-vitest.mjs run --config test/vitest/vitest.gateway.config.ts src/gateway/chat-abort.test.ts src/gateway/server-chat.agent-events.test.ts
Test Files  4 passed (4)
Tests  192 passed (192)

git diff --check passed.

Real runtime persistence rejection proof after the formatter update:

A temporary node --import tsx script seeded a real OPENCLAW_STATE_DIR with state/agents/main/sessions/sessions.json, denied writes to that sessions directory with icacls, then invoked createAgentEventHandler with the real persistGatewaySessionLifecycleEvent path. The script was not committed and used synthetic ids only.

[gateway] failed to persist terminal session lifecycle event for run proof-run: Error: EPERM: operation not permitted, open 'C:\Users\16500\AppData\Local\Temp\openclaw-pr-97839-proof-pqeeeO\state\agents\main\sessions\sessions.json.24092.c92dfce1-5b4b-4b11-b00b-19690d9c141b.tmp': code=EPERM
sessions.changed fallback status=done run=proof-run

Formatter safety proof:

The focused handler test now rejects with Error("disk full sk-abcdefghijklmnopqrstuvwxyz123456") and asserts the gateway log contains the formatted/redacted value sk-abc…3456, proving the new catch uses formatForLog(err) instead of raw String(err).

Autoreview note: attempted python .agents\skills\autoreview\scripts\autoreview --mode local, but the helper failed before review on Windows path handling with NotADirectoryError: [WinError 267] in this non-ASCII worktree path, even when retried through a subst drive.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: XS labels Jun 29, 2026
@LZY3538
LZY3538 marked this pull request as ready for review June 29, 2026 15:11
@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 3, 2026, 5:05 PM ET / 21:05 UTC.

Summary
The PR adds a gateway error log when terminal session lifecycle persistence rejects and updates the existing agent-events test to assert one redacted log before the fallback session broadcast.

PR surface: Source +4, Tests +12. Total +16 across 2 files.

Reproducibility: yes. source-reproducible. Current main catches rejected terminal lifecycle persistence only to broadcast fallback state, and the PR turns that rejected promise into an asserted log call.

Review metrics: none identified.

Root-cause cluster
Relationship: canonical
Canonical: #97839
Summary: This PR is the open canonical fix candidate for the gateway terminal persistence logging bug; the linked issue remains open and several sibling cleanup-path PRs are duplicate or superseded attempts.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Risk before merge

  • [P1] At review time, the required check checks-node-compact-small-whole-2 was still pending, so merge should wait for that check to complete.

Maintainer options:

  1. Decide the mitigation before merge
    Land this owner-boundary logging fix once required CI is green, then let it close [Bug]: Unhandled persistence failures in chat-abort.ts silently swallow errors and risk memory leaks #97795.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P2] No repair lane: the branch already contains the narrow fix and proof; remaining action is maintainer merge review after required checks complete.

Security
Cleared: No supply-chain, permission, or credential-handling changes were introduced, and the new diagnostic uses formatForLog with a redaction assertion.

Review details

Best possible solution:

Land this owner-boundary logging fix once required CI is green, then let it close #97795.

Do we have a high-confidence way to reproduce the issue?

Yes, source-reproducible. Current main catches rejected terminal lifecycle persistence only to broadcast fallback state, and the PR turns that rejected promise into an asserted log call.

Is this the best way to solve the issue?

Yes. Logging once in createAgentEventHandler at the persistence owner boundary with formatForLog(err) is narrower and safer than adding downstream chat-abort cleanup logs that could miss or duplicate the shared promise failure.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 1755a9dc5bce.

Label changes

Label justifications:

  • P2: This is a normal-priority gateway observability and session-state bug fix with limited blast radius and no evidence of an active outage.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes after-fix terminal output from a denied-write runtime path showing both the gateway error log and the fallback sessions.changed broadcast.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal output from a denied-write runtime path showing both the gateway error log and the fallback sessions.changed broadcast.
Evidence reviewed

PR surface:

Source +4, Tests +12. Total +16 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 5 1 +4
Tests 1 13 1 +12
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 18 2 +16

What I checked:

  • Repository policy read: Root AGENTS.md and the scoped gateway guide were read fully; the gateway owner-boundary guidance shaped the review. (AGENTS.md:1, 1755a9dc5bce)
  • Current main behavior: Current main creates the terminal lifecycle persistence promise and catches rejection only to broadcast the fallback snapshot, with no diagnostic log. (src/gateway/server-chat.ts:719, 1755a9dc5bce)
  • PR implementation: The PR head logs the failed terminal persistence with formatted session, run, and error fields before preserving the existing fallback broadcast. (src/gateway/server-chat.ts:720, 715a99416658)
  • Regression coverage: The PR test rejects the persistence write with a secret-shaped error string and asserts exactly one redacted gateway log plus unchanged fallback behavior. (src/gateway/server-chat.agent-events.test.ts:2543, 715a99416658)
  • Formatter contract: formatForLog formats Error values through redaction and length capping before they reach gateway logs. (src/gateway/ws-log.ts:115, 1755a9dc5bce)
  • Logger contract: logError accepts one message string and routes a gateway-prefixed message through the subsystem logger path, matching the PR call shape. (src/logger.ts:77, 1755a9dc5bce)

Likely related people:

  • ooiuuii: Recent GitHub history shows merged gateway restart and terminal ownership work across server-chat, chat-abort, and runtime subscription surfaces. (role: feature-history contributor; confidence: high; commits: d20fdf3b3842; files: src/gateway/server-chat.ts, src/gateway/chat-abort.ts, src/gateway/server-runtime-subscriptions.ts)
  • steipete: Recent history shows adjacent gateway lifecycle snapshot work, and the latest PR commit tightens the log identity on this same surface. (role: recent adjacent contributor; confidence: medium; commits: 2b61d38a455c, 715a99416658; files: src/gateway/server-chat.ts, src/gateway/session-lifecycle-state.ts, src/gateway/server-chat.agent-events.test.ts)
  • hexsprite: Authored the gateway log formatting/redaction work that this PR relies on for safe error logging. (role: adjacent formatter contributor; confidence: medium; commits: 86c1622a3a3c; files: src/gateway/ws-log.ts, src/gateway/ws-log.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jun 29, 2026
@LZY3538

LZY3538 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

I added the requested real logger proof to the PR Evidence section. It shows the gateway subsystem logger emitting the exact terminal lifecycle persistence failure message, paired with the focused handler test that drives the rejected persistence path and asserts the same logError(...) call before the fallback sessions.changed broadcast.

@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@LZY3538

LZY3538 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Addressed the latest review:

  • Changed the new terminal lifecycle persistence catch to use formatForLog(err) instead of String(err).
  • Updated the focused handler test to prove a fake sk-... token is formatted/redacted in the emitted gateway log message.
  • Updated the PR Evidence section with real runtime proof: a temporary node --import tsx script seeded a real session store, denied writes to the sessions directory, invoked createAgentEventHandler through the real persistGatewaySessionLifecycleEvent path, and captured both the gateway EPERM log and fallback sessions.changed status=done output.

Latest local proof:

node scripts/run-vitest.mjs run --config test/vitest/vitest.gateway.config.ts src/gateway/chat-abort.test.ts src/gateway/server-chat.agent-events.test.ts
Test Files  4 passed (4)
Tests  192 passed (192)

git diff --check passed.

@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 29, 2026
@LZY3538
LZY3538 force-pushed the codex/log-chat-abort-persistence branch from f3abe13 to f6960df Compare July 2, 2026 13:18
@clawsweeper clawsweeper Bot removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 3, 2026
@steipete steipete self-assigned this Jul 3, 2026
@steipete
steipete force-pushed the codex/log-chat-abort-persistence branch from f6960df to 715a994 Compare July 3, 2026 20:55
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 3, 2026
@steipete

steipete commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Land-ready verification:

  • Improved the owner-boundary diagnostic to include redacted session and run correlation while keeping downstream cleanup catches silent, so one terminal persistence failure produces one useful log.
  • Focused proof: node scripts/run-vitest.mjs src/gateway/chat-abort.test.ts src/gateway/server-chat.agent-events.test.ts src/gateway/server-methods/chat.abort-persistence.test.ts — 374 passed.
  • Live logger proof: the production gateway logger emitted the correlated failure to both console and JSON transport and redacted a synthetic secret-shaped session key.
  • Real failure-path proof: the contributor's Windows production EPERM reproduction shows the persistence failure plus the existing fallback projection; this patch makes that formerly silent failure diagnosable without changing recovery.
  • Fresh Codex autoreview: clean for the fixup and full branch.
  • Exact PR head 715a99416658a9a8e3b4ea87c1a01441c59ed1da: required hosted CI/Testbox gates green.

Known gap: I did not recreate the Windows filesystem lock locally; the contributor's production trace covers that platform-specific trigger, while local tests and the real logger cover the changed owner and output path.

@steipete
steipete merged commit 7d593bb into openclaw:main Jul 3, 2026
121 of 125 checks passed
@steipete

steipete commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 4, 2026
* fix: log terminal session persistence failures

* fix: format terminal persistence error logs

* fix(gateway): identify failed terminal persistence

---------

Co-authored-by: Peter Steinberger <[email protected]>
masatohoshino added a commit to masatohoshino/openclaw that referenced this pull request Jul 5, 2026
The gateway session-lifecycle "start" event persistence
(persistGatewaySessionLifecycleEvent, which surfaces write failures via
requireWriteSuccess) was fired as void ...catch(() => undefined), swallowing
the rejection with zero logging. A failed start-marker write silently dropped
the run's start record from restart-recovery accounting, with no
operator-visible trace.

The sibling terminal-phase catch already logs this since openclaw#97839; the start
path was the unfixed sibling. Mirror that fix: log the swallowed start-phase
persistence failure with the same redacted message shape via formatForLog,
keeping the fire-and-forget semantics unchanged. Adds a focused regression
test asserting the log fires on start-persist rejection.
steipete pushed a commit that referenced this pull request Jul 5, 2026
The gateway session-lifecycle "start" event persistence
(persistGatewaySessionLifecycleEvent, which surfaces write failures via
requireWriteSuccess) was fired as void ...catch(() => undefined), swallowing
the rejection with zero logging. A failed start-marker write silently dropped
the run's start record from restart-recovery accounting, with no
operator-visible trace.

The sibling terminal-phase catch already logs this since #97839; the start
path was the unfixed sibling. Mirror that fix: log the swallowed start-phase
persistence failure with the same redacted message shape via formatForLog,
keeping the fire-and-forget semantics unchanged. Adds a focused regression
test asserting the log fires on start-persist rejection.
steipete pushed a commit that referenced this pull request Jul 5, 2026
The gateway session-lifecycle "start" event persistence
(persistGatewaySessionLifecycleEvent, which surfaces write failures via
requireWriteSuccess) was fired as void ...catch(() => undefined), swallowing
the rejection with zero logging. A failed start-marker write silently dropped
the run's start record from restart-recovery accounting, with no
operator-visible trace.

The sibling terminal-phase catch already logs this since #97839; the start
path was the unfixed sibling. Mirror that fix: log the swallowed start-phase
persistence failure with the same redacted message shape via formatForLog,
keeping the fire-and-forget semantics unchanged. Adds a focused regression
test asserting the log fires on start-persist rejection.
steipete added a commit that referenced this pull request Jul 5, 2026
* fix(cron): reject sub-millisecond durations

* fix(skill-workshop): preserve proposal terminal newline

Preserve proposal_content exactly at the agent tool boundary and make
renderProposalMarkdown defensively emit a terminal newline.

Add focused regressions for the tool write path and markdown renderer.

* fix(skill-workshop): reject blank raw proposal content

* fix: treat empty-string optional integer tool params as unset

Optional positive-integer tool params (e.g. Telegram replyTo/threadId)
threw ToolInputError when a tool-calling model populated them with an
empty-string or whitespace-only default. Those defaults carry no value,
so readPositiveIntegerParam/readNonNegativeIntegerParam now treat a
blank string as unset (undefined) instead of throwing, while still
rejecting genuinely invalid present values (0, "42.5", "-3"). This
prevents silent message-delivery failures when models emit empty
routing-param defaults. Adds unit tests covering blank vs invalid.

* fix(gateway): log start session persistence failures

The gateway session-lifecycle "start" event persistence
(persistGatewaySessionLifecycleEvent, which surfaces write failures via
requireWriteSuccess) was fired as void ...catch(() => undefined), swallowing
the rejection with zero logging. A failed start-marker write silently dropped
the run's start record from restart-recovery accounting, with no
operator-visible trace.

The sibling terminal-phase catch already logs this since #97839; the start
path was the unfixed sibling. Mirror that fix: log the swallowed start-phase
persistence failure with the same redacted message shape via formatForLog,
keeping the fire-and-forget semantics unchanged. Adds a focused regression
test asserting the log fires on start-persist rejection.

* fix(memory): report close-time pending work failures

* fix(shared): return "" from sliceUtf16Safe when end <= start, matching native .slice

sliceUtf16Safe silently swapped reversed bounds (to < from) instead of
returning "" like String.prototype.slice, creating a subtle footgun for
callers with dynamic start/end pairs.

Caller scan across src/, extensions/, and packages/ confirmed no production
code relies on the old swap behavior — all callers use (text, 0, N) or
(text, -N) forms only.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix(plugins): require plugin manifest in npm verifier

* fix(android): propagate CancellationException in CameraHandler catch blocks

Catch (err: Throwable) swallows kotlinx.coroutines.CancellationException,
breaking structured concurrency when the coroutine scope is cancelled
during camera operations (handleList/handleSnap/handleClip).

Add CancellationException rethrow before each Throwable catch to match
the existing pattern used in GatewaySession and TalkModeManager.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

* fix(android): propagate CancellationException past GatewaySession invoke boundary

* chore: sync native i18n inventory after gateway session line shift

* fix(agents): prevent native hook relay bridge race condition on renew and registration

Remove synchronous bridge record write after server.listen() that races
before the TCP server binds, and guard renew handler with server.listening
check to prevent stale relay registrations.

Closes #98650

* fix: harden small reliability fixes

Co-authored-by: cxbAsDev <[email protected]>

* docs(agents): explain buffered LSP spawn failures

* docs(agents): clarify LSP spawn timeout invariant

---------

Co-authored-by: qingminlong <[email protected]>
Co-authored-by: anyech <[email protected]>
Co-authored-by: snotty <[email protected]>
Co-authored-by: masatohoshino <[email protected]>
Co-authored-by: lin-hongkuan <[email protected]>
Co-authored-by: simon-w <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: 宇宙熊Yzx <[email protected]>
Co-authored-by: xialonglee <[email protected]>
Co-authored-by: nankingjing <[email protected]>
Co-authored-by: cxbAsDev <[email protected]>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 6, 2026
* fix(cron): reject sub-millisecond durations

* fix(skill-workshop): preserve proposal terminal newline

Preserve proposal_content exactly at the agent tool boundary and make
renderProposalMarkdown defensively emit a terminal newline.

Add focused regressions for the tool write path and markdown renderer.

* fix(skill-workshop): reject blank raw proposal content

* fix: treat empty-string optional integer tool params as unset

Optional positive-integer tool params (e.g. Telegram replyTo/threadId)
threw ToolInputError when a tool-calling model populated them with an
empty-string or whitespace-only default. Those defaults carry no value,
so readPositiveIntegerParam/readNonNegativeIntegerParam now treat a
blank string as unset (undefined) instead of throwing, while still
rejecting genuinely invalid present values (0, "42.5", "-3"). This
prevents silent message-delivery failures when models emit empty
routing-param defaults. Adds unit tests covering blank vs invalid.

* fix(gateway): log start session persistence failures

The gateway session-lifecycle "start" event persistence
(persistGatewaySessionLifecycleEvent, which surfaces write failures via
requireWriteSuccess) was fired as void ...catch(() => undefined), swallowing
the rejection with zero logging. A failed start-marker write silently dropped
the run's start record from restart-recovery accounting, with no
operator-visible trace.

The sibling terminal-phase catch already logs this since openclaw#97839; the start
path was the unfixed sibling. Mirror that fix: log the swallowed start-phase
persistence failure with the same redacted message shape via formatForLog,
keeping the fire-and-forget semantics unchanged. Adds a focused regression
test asserting the log fires on start-persist rejection.

* fix(memory): report close-time pending work failures

* fix(shared): return "" from sliceUtf16Safe when end <= start, matching native .slice

sliceUtf16Safe silently swapped reversed bounds (to < from) instead of
returning "" like String.prototype.slice, creating a subtle footgun for
callers with dynamic start/end pairs.

Caller scan across src/, extensions/, and packages/ confirmed no production
code relies on the old swap behavior — all callers use (text, 0, N) or
(text, -N) forms only.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix(plugins): require plugin manifest in npm verifier

* fix(android): propagate CancellationException in CameraHandler catch blocks

Catch (err: Throwable) swallows kotlinx.coroutines.CancellationException,
breaking structured concurrency when the coroutine scope is cancelled
during camera operations (handleList/handleSnap/handleClip).

Add CancellationException rethrow before each Throwable catch to match
the existing pattern used in GatewaySession and TalkModeManager.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

* fix(android): propagate CancellationException past GatewaySession invoke boundary

* chore: sync native i18n inventory after gateway session line shift

* fix(agents): prevent native hook relay bridge race condition on renew and registration

Remove synchronous bridge record write after server.listen() that races
before the TCP server binds, and guard renew handler with server.listening
check to prevent stale relay registrations.

Closes openclaw#98650

* fix: harden small reliability fixes

Co-authored-by: cxbAsDev <[email protected]>

* docs(agents): explain buffered LSP spawn failures

* docs(agents): clarify LSP spawn timeout invariant

---------

Co-authored-by: qingminlong <[email protected]>
Co-authored-by: anyech <[email protected]>
Co-authored-by: snotty <[email protected]>
Co-authored-by: masatohoshino <[email protected]>
Co-authored-by: lin-hongkuan <[email protected]>
Co-authored-by: simon-w <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: 宇宙熊Yzx <[email protected]>
Co-authored-by: xialonglee <[email protected]>
Co-authored-by: nankingjing <[email protected]>
Co-authored-by: cxbAsDev <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: XS status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Unhandled persistence failures in chat-abort.ts silently swallow errors and risk memory leaks

2 participants