diff --git a/CHANGELOG.md b/CHANGELOG.md index a7d8b0b76aa..c8e02b9b157 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Docs: https://docs.openclaw.ai - Fireworks/FirePass: disable Kimi K2.5 Turbo reasoning output by forcing thinking off on the FirePass path and hardening the provider wrapper so hidden reasoning no longer leaks into visible replies. (#63607) Thanks @frankekn. - Sessions/model selection: preserve catalog-backed session model labels and keep already-qualified session model refs stable when catalog metadata is unavailable, so Control UI model selection survives reloads without bogus provider-prefixed values. (#61382) Thanks @Mule-ME. - Gateway/startup: keep WebSocket RPC available while channels and plugin sidecars start, hold `chat.history` unavailable until startup sidecars finish so synchronous history reads cannot stall startup (reported in #63450), refresh advertised gateway methods after deferred plugin reloads, and enforce the pre-auth WebSocket upgrade budget before the no-handler 503 path so upgrade floods cannot bypass connection limits during that window. (#63480) Thanks @neeravmakwana. +- Gateway/tailscale: start Tailscale exposure and the gateway update check before awaiting channel and plugin sidecar startup so remote operators are not locked out when startup sidecars stall. ## 2026.4.9 diff --git a/src/gateway/server.impl.ts b/src/gateway/server.impl.ts index dafc0b44264..451ac81f737 100644 --- a/src/gateway/server.impl.ts +++ b/src/gateway/server.impl.ts @@ -1343,9 +1343,7 @@ export async function startGatewayServer( const canvasHostServerPort = (canvasHostServer as CanvasHostServer | null)?.port; - const unavailableGatewayMethods = new Set( - minimalTestGateway ? [] : ["chat.history"], - ); + const unavailableGatewayMethods = new Set(minimalTestGateway ? [] : ["chat.history"]); const gatewayRequestContext: import("./server-methods/types.js").GatewayRequestContext = { deps, cron, @@ -1489,21 +1487,6 @@ export async function startGatewayServer( broadcast, context: gatewayRequestContext, }); - - if (!minimalTestGateway) { - log.info("starting channels and sidecars..."); - ({ pluginServices } = await startGatewaySidecars({ - cfg: gatewayPluginConfigAtStart, - pluginRegistry, - defaultWorkspaceDir, - deps, - startChannels, - log, - logHooks, - logChannels, - })); - unavailableGatewayMethods.delete("chat.history"); - } logGatewayStartup({ cfg: cfgAtStart, bindHost, @@ -1536,6 +1519,21 @@ export async function startGatewayServer( logTailscale, }); + if (!minimalTestGateway) { + log.info("starting channels and sidecars..."); + ({ pluginServices } = await startGatewaySidecars({ + cfg: gatewayPluginConfigAtStart, + pluginRegistry, + defaultWorkspaceDir, + deps, + startChannels, + log, + logHooks, + logChannels, + })); + unavailableGatewayMethods.delete("chat.history"); + } + // Run gateway_start plugin hook (fire-and-forget) if (!minimalTestGateway) { const hookRunner = getGlobalHookRunner();