From a30698166b841d958f5d1615ee11c63d69baf7c1 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 28 Apr 2026 07:55:04 +0100 Subject: [PATCH] fix(wizard): pin setup token for health check --- CHANGELOG.md | 1 + src/commands/health.test.ts | 21 +++++++++++++++++++++ src/commands/health.ts | 11 ++++++++++- src/wizard/setup.finalize.test.ts | 2 ++ src/wizard/setup.finalize.ts | 10 +++++++++- 5 files changed, 43 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4084a8a4384..6de0f1221e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Docs: https://docs.openclaw.ai - Control UI/WebChat: keep large attachment payloads out of Lit state and optimistic chat messages, using object URL previews plus send-time payload serialization so PDF/image uploads no longer trigger `RangeError: Maximum call stack size exceeded`. Fixes #73360; refs #54378 and #63432. Thanks @hejunhui-73, @Ansub, and @christianhernandez3-afk. - Agents/models: keep per-agent primary models strict when `fallbacks` is omitted, so probe-only custom providers are not tried as hidden fallback candidates unless the agent explicitly opts in. Fixes #73332. Thanks @haumanto. - Gateway/models: add `models.pricing.enabled` so offline or restricted-network installs can skip startup OpenRouter and LiteLLM pricing-catalog fetches while keeping explicit model costs working. Fixes #53639. Thanks @callebtc, @palewire, and @rjdjohnston. +- Onboarding: pin the final QuickStart health check to the just-configured setup token so stale `OPENCLAW_GATEWAY_TOKEN` values or older config tokens do not produce false gateway-token-mismatch failures after setup. Fixes #72203. Thanks @galiniliev. - Cron/Telegram: preserve explicit `:topic:` delivery targets over stale session-derived thread IDs when isolated cron announces to Telegram forum topics. Carries forward #59069; refs #49704 and #43808. Thanks @roytong9. - Build/runtime: write the runtime-postbuild stamp after `pnpm build` writes the build stamp, so the next CLI invocation does not re-sync runtime artifacts after a successful build. Fixes #73151. Thanks @bittoby. - CLI/channels: list configured chat channel accounts from read-only setup metadata even when the standalone CLI has not loaded the runtime channel registry, so `openclaw channels list` shows Telegram accounts before auth providers. Fixes #73319 and #73322. Thanks @mlaihk. diff --git a/src/commands/health.test.ts b/src/commands/health.test.ts index c5ad3f5cce9..db36711ce8a 100644 --- a/src/commands/health.test.ts +++ b/src/commands/health.test.ts @@ -97,6 +97,27 @@ describe("healthCommand", () => { expect(parsed.sessions.count).toBe(1); }); + it("passes explicit gateway credentials through to the gateway call", async () => { + const snapshot = createHealthSummary({ + channels: {}, + channelOrder: [], + channelLabels: {}, + }); + callGatewayMock.mockResolvedValueOnce(snapshot); + + await healthCommand( + { json: true, timeoutMs: 5000, config: {}, token: "setup-token" }, + runtime as never, + ); + + expect(callGatewayMock).toHaveBeenCalledWith( + expect.objectContaining({ + method: "health", + token: "setup-token", + }), + ); + }); + it("formats per-account probe timings", () => { const summary = createHealthSummary({ channels: { diff --git a/src/commands/health.ts b/src/commands/health.ts index 5f5c01db314..9c23ec33d54 100644 --- a/src/commands/health.ts +++ b/src/commands/health.ts @@ -451,7 +451,14 @@ export async function getHealthSnapshot(params?: { } export async function healthCommand( - opts: { json?: boolean; timeoutMs?: number; verbose?: boolean; config?: OpenClawConfig }, + opts: { + json?: boolean; + timeoutMs?: number; + verbose?: boolean; + config?: OpenClawConfig; + token?: string; + password?: string; + }, runtime: RuntimeEnv, ) { const cfg = opts.config ?? (await readBestEffortHealthConfig()); @@ -468,6 +475,8 @@ export async function healthCommand( params: opts.verbose ? { probe: true } : undefined, timeoutMs: opts.timeoutMs, config: cfg, + token: opts.token, + password: opts.password, }), ); // Gateway reachability defines success; channel issues are reported but not fatal here. diff --git a/src/wizard/setup.finalize.test.ts b/src/wizard/setup.finalize.test.ts index 0cf75eba601..78c2aa17786 100644 --- a/src/wizard/setup.finalize.test.ts +++ b/src/wizard/setup.finalize.test.ts @@ -562,6 +562,7 @@ describe("finalizeSetupWizard", () => { }); it("uses the setup token for health checks to avoid local env token drift", async () => { + vi.stubEnv("OPENCLAW_GATEWAY_TOKEN", "env-token"); const prompter = createLaterPrompter(); await finalizeSetupWizard({ @@ -599,6 +600,7 @@ describe("finalizeSetupWizard", () => { expect.objectContaining({ json: false, timeoutMs: 10_000, + token: "session-token", config: expect.objectContaining({ gateway: expect.objectContaining({ auth: expect.objectContaining({ diff --git a/src/wizard/setup.finalize.ts b/src/wizard/setup.finalize.ts index f2588f8f917..477b4909dde 100644 --- a/src/wizard/setup.finalize.ts +++ b/src/wizard/setup.finalize.ts @@ -266,7 +266,15 @@ export async function finalizeSetupWizard( }, } : nextConfig; - await healthCommand({ json: false, timeoutMs: 10_000, config: healthConfig }, runtime); + await healthCommand( + { + json: false, + timeoutMs: 10_000, + config: healthConfig, + token: settings.authMode === "token" ? settings.gatewayToken : undefined, + }, + runtime, + ); } catch (err) { runtime.error(formatHealthCheckFailure(err)); await prompter.note(