openclaw - ✅(Solved) Fix Gateway crashes: log undefined in channel error handler (server.impl line 2047) [2 pull requests, 2 comments, 3 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#75168Fetched 2026-05-01 05:37:23
View on GitHub
Comments
2
Participants
3
Timeline
8
Reactions
2
Author
Timeline (top)
commented ×2cross-referenced ×2referenced ×2mentioned ×1

Error Message

[openclaw] Unhandled promise rejection: TypeError: Cannot read properties of undefined (reading 'error') at file:///usr/local/lib/node_modules/openclaw/dist/server.impl-BoLlD_Zm.js:2047:10

Root Cause

In server.impl-BoLlD_Zm.js, the channel startup promise chain uses log.error?.(...) — but log itself can be undefined by the time the .catch() or .then() handlers execute (likely because the channel's logger is cleaned up before a pending promise resolves during a race condition).

The optional chaining ?. only guards the function call (error?.()), not the property access on log. When log is undefined, log.error throws.

Affected lines: 1959, 2011, 2040, 2047, 2065

Fix Action

Fix

Change log.error?.(...)log?.error?.(...) at those locations.

Workaround

Manually patch the installed dist file with the log?.error?.() pattern.

PR fix notes

PR #75172: fix(gateway): guard against undefined channelLogs entry in async channel lifecycle handlers

Description (problem / solution / changelog)

Summary

Fixes #75168.

Root cause: channelLogs[channelId] can be evicted from the map during a config-reload race while a promise chain from a prior startChannelInternal call is still in flight. The existing log.error?.() guards protected against a missing .error method on the logger object, but not against log itself being undefined — resulting in TypeError: Cannot read properties of undefined (reading 'error') and a gateway crash.

Fix: Capture log as SubsystemLogger | undefined at task start, then apply optional-chain guards (log?.error?.(), log?.info?.()) on all six async continuation call sites inside startChannelInternal. This matches the existing pattern already used at line 699 (channelLogs[plugin.id]?.error?.()).

Changes

  • src/gateway/server-channels.ts: cast log as potentially undefined; update 6 async call sites from log.X?.() to log?.X?.()
  • src/gateway/server-channels.test.ts: regression test using a Proxy-backed channelLogs map that returns undefined after a flag is set, confirming no TypeError when .catch() and backoff-restart handlers fire without a live logger

Test plan

  • pnpm vitest run src/gateway/server-channels.test.ts — 26/26 pass (includes new regression test)
  • New test: Proxy-backed channelLogs evicts entry mid-run; vi.advanceTimersByTimeAsync(50) must resolve without throwing

🤖 Generated with Claude Code

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/gateway/server-channels.test.ts (modified, +29/-0)
  • src/gateway/server-channels.ts (modified, +11/-7)
  • src/gateway/server.impl.ts (modified, +8/-0)

PR #75331: fix(gateway/server-channels): guard against undefined channel logger (#75168)

Description (problem / solution / changelog)

Summary

Fixes #75168.

The channel auto-restart promise chain in createChannelManager reads the per-channel logger via const log = channelLogs[channelId]. The type is Record<ChannelId, SubsystemLogger>, so TypeScript treats log as non-nullable, but at runtime the lookup can return undefined if a channel plugin's id was registered without a corresponding channelLogs entry (race between plugin registration and logger attachment). When the channel's startup task then exits or errors, the .catch / .then handlers call log.error?.(...) — and the optional chain only guards the function call, not the property access.

Result: TypeError: Cannot read properties of undefined (reading 'error') surfacing as an unhandled rejection that crashes the gateway every ~5 minutes under launchd KeepAlive: true (reported against feishu/whatsapp on v2026.4.27).

Changes

src/gateway/server-channels.ts — switch every log.<level>?.(...) access in the affected closures to log?.<level>?.(...). Six call sites (lines 407, 484, 518, 523, 545, 549, 663). The same safe-access pattern is already used at line 699 (channelLogs[plugin.id]?.error?.(...)).

-            log.error?.(`[${id}] ${label}: ${formatErrorMessage(error)}`);
+            log?.error?.(`[${id}] ${label}: ${formatErrorMessage(error)}`);

src/gateway/server-channels.test.ts — regression test that spins up the channel manager with an intentionally-empty channelLogs map and asserts that a startAccount failure is captured into the runtime snapshot's lastError rather than escaping as an unhandled rejection.

Verified

  • Without the fix, the new test fails on the assertion expect(unhandledRejection).not.toHaveBeenCalled() (the TypeError escapes).
  • With the fix, all 26 tests in src/gateway/server-channels.test.ts pass.
  • Repo tsgo --noEmit reports unrelated pre-existing errors in src/agents/pi-embedded-runner/run/attempt.test.ts and src/agents/pi-embedded-runner.sanitize-session-history.test.ts — confirmed they exist on a clean upstream main without my change.

Notes

  • I left the typed params.log.X?.(...) calls in src/gateway/exec-approval-ios-push.ts alone — that one's log is typed as required GatewayLikeLogger and isn't pulled out of the racing channelLogs map. Not the same bug shape.
  • Module-scoped const log = createSubsystemLogger(...) in channel-health-monitor.ts likewise can't be undefined and was left untouched.

Changed files

  • src/gateway/server-channels.test.ts (modified, +37/-0)
  • src/gateway/server-channels.ts (modified, +7/-7)

Code Example

[openclaw] Unhandled promise rejection: TypeError: Cannot read properties of undefined (reading 'error')
    at file:///usr/local/lib/node_modules/openclaw/dist/server.impl-BoLlD_Zm.js:2047:10
RAW_BUFFERClick to expand / collapse

Bug

The gateway process crashes repeatedly (~every 5 minutes) with:

[openclaw] Unhandled promise rejection: TypeError: Cannot read properties of undefined (reading 'error')
    at file:///usr/local/lib/node_modules/openclaw/dist/server.impl-BoLlD_Zm.js:2047:10

Root Cause

In server.impl-BoLlD_Zm.js, the channel startup promise chain uses log.error?.(...) — but log itself can be undefined by the time the .catch() or .then() handlers execute (likely because the channel's logger is cleaned up before a pending promise resolves during a race condition).

The optional chaining ?. only guards the function call (error?.()), not the property access on log. When log is undefined, log.error throws.

Affected lines: 1959, 2011, 2040, 2047, 2065

Fix

Change log.error?.(...)log?.error?.(...) at those locations.

Environment

  • OpenClaw 2026.4.27 (cbc2ba0)
  • Node.js 22 on macOS
  • launchd managed (KeepAlive: true)
  • Triggers: channel exit/error during plugin registration (feishu, whatsapp)

Workaround

Manually patch the installed dist file with the log?.error?.() pattern.

extent analysis

TL;DR

Update the log.error calls to log?.error?.() in the affected lines of server.impl-BoLlD_Zm.js to prevent the gateway process from crashing due to unhandled promise rejections.

Guidance

  • Verify the issue by checking the stacktrace for the TypeError: Cannot read properties of undefined (reading 'error') error and confirming that the log object is undefined when the error occurs.
  • Apply the suggested fix by changing log.error?.(...) to log?.error?.(...) at lines 1959, 2011, 2040, 2047, and 2065 in server.impl-BoLlD_Zm.js.
  • As a temporary workaround, manually patch the installed dist file with the updated log?.error?.() pattern.
  • Test the fix by restarting the gateway process and monitoring for crashes.

Example

// Before
log.error?.('Error message');

// After
log?.error?.('Error message');

Notes

This fix assumes that the log object is intentionally set to undefined in certain cases, and that the optional chaining ?. is sufficient to prevent the error. If the log object should never be undefined, further investigation into why it is being set to undefined may be necessary.

Recommendation

Apply the workaround by manually patching the installed dist file with the updated log?.error?.() pattern, as this is a straightforward and targeted fix for the identified issue.

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 Gateway crashes: log undefined in channel error handler (server.impl line 2047) [2 pull requests, 2 comments, 3 participants]