The test previously asserted that a valid snapshot without gateway.mode
blocks startup. After defaulting gateway.mode to 'local' when unset,
the gateway should start successfully in this scenario — update the
test to verify the new expected behavior.
Co-authored-by: Brad Groux <bradgroux@users.noreply.github.com>
After v2026.3.24 introduced a gateway.mode guard, startup fails on
Windows (and other platforms) when the config file exists but doesn't
contain an explicit gateway.mode value. This happens after 'openclaw
onboard' writes a minimal config without gateway settings.
Default to 'local' when the mode is unset, restoring pre-3.24 behavior
where the gateway started without requiring an explicit mode.
Fixes#54801
Co-authored-by: Brad Groux <bradgroux@users.noreply.github.com>
* fix: import CHANNEL_IDS from leaf module to avoid TDZ on init (#48832)
schema.ts and validation.ts imported CHANNEL_IDS from channels/registry.js,
which re-exports from channels/ids.js but also imports plugins/runtime.js.
When the bundler resolves this dependency graph, the re-exported CHANNEL_IDS
can be undefined at the point config/validation.ts evaluates (temporal dead
zone), causing 'CHANNEL_IDS is not iterable' on startup.
Fix: import CHANNEL_IDS directly from channels/ids.js (the leaf module with
zero heavy dependencies) and normalizeChatChannelId from channels/chat-meta.js.
Fixes#48832
* fix: improve WS handshake reliability on slow-startup environments (#48736)
On Windows with large dist bundles (46MB/639 files), heavy synchronous
module loading blocks the event loop during CLI startup, preventing
timely processing of the connect.challenge frame and causing ~80%
handshake timeout failures.
Changes:
- Yield event loop (setImmediate) before starting WS connection in
callGateway to let pending I/O drain after heavy module loading
- Add OPENCLAW_CONNECT_CHALLENGE_TIMEOUT_MS env var override for
client-side connect challenge timeout (server already has
OPENCLAW_HANDSHAKE_TIMEOUT_MS)
- Include diagnostic timing in challenge timeout error messages
(elapsed vs limit) for easier debugging
- Add tests for env var override and resolution logic
---------
Co-authored-by: Brad Groux <bradgroux@users.noreply.github.com>
schema.ts and validation.ts imported CHANNEL_IDS from channels/registry.js,
which re-exports from channels/ids.js but also imports plugins/runtime.js.
When the bundler resolves this dependency graph, the re-exported CHANNEL_IDS
can be undefined at the point config/validation.ts evaluates (temporal dead
zone), causing 'CHANNEL_IDS is not iterable' on startup.
Fix: import CHANNEL_IDS directly from channels/ids.js (the leaf module with
zero heavy dependencies) and normalizeChatChannelId from channels/chat-meta.js.
Fixes#48832
Co-authored-by: Brad Groux <bradgroux@users.noreply.github.com>
Fix stale lock files from crashed gateway processes blocking new invocations on Windows/macOS. Detect PID recycling to avoid false positive lock conflicts, and add startup progress indicator.
Thanks @TonyDerek-dot
getActionAvailabilityState in createApproverRestrictedNativeApprovalAdapter
was gating on both hasApprovers AND isNativeDeliveryEnabled, causing
Telegram exec approvals to report "not allowed" when
channels.telegram.execApprovals.target was configured but
execApprovals.enabled was not explicitly true. The availability check
should only depend on whether approvers exist; native delivery mode is
a routing concern handled downstream.