From 397cf2b9ff475bb4920854947e28414e59ce2d6c Mon Sep 17 00:00:00 2001 From: sallyom Date: Fri, 8 May 2026 00:20:45 -0400 Subject: [PATCH] fix: clarify gateway version mismatch warnings --- src/cli/daemon-cli/status.print.test.ts | 8 +++++--- src/cli/daemon-cli/status.print.ts | 4 ++-- src/commands/doctor-gateway-health.test.ts | 22 ++++++++++++++++------ src/commands/doctor-gateway-health.ts | 9 ++++----- src/config/io.compat.test.ts | 17 ++++++++++++----- src/config/io.ts | 8 +++++--- 6 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/cli/daemon-cli/status.print.test.ts b/src/cli/daemon-cli/status.print.test.ts index 80b49363159..a38f5c17e4e 100644 --- a/src/cli/daemon-cli/status.print.test.ts +++ b/src/cli/daemon-cli/status.print.test.ts @@ -157,7 +157,7 @@ describe("printDaemonStatus", () => { expect(runtime.log).toHaveBeenCalledWith(expect.stringContaining("Capability: write-capable")); }); - it("prints CLI and gateway versions with stale wrapper guidance when they differ", () => { + it("prints CLI and gateway versions with readable guidance when they differ", () => { printDaemonStatus( { cli: { @@ -195,10 +195,12 @@ describe("printDaemonStatus", () => { ); expect(runtime.log).toHaveBeenCalledWith(expect.stringContaining("Gateway version: 2026.5.6")); expect(runtime.error).toHaveBeenCalledWith( - expect.stringContaining("CLI/runtime version skew detected"), + expect.stringContaining("this OpenClaw command is version 2026.4.23"), ); expect(runtime.error).toHaveBeenCalledWith( - expect.stringContaining("stale PATH/global wrappers"), + expect.stringContaining( + "if this mismatch is unexpected, update PATH so `openclaw` points to the version you want", + ), ); }); diff --git a/src/cli/daemon-cli/status.print.ts b/src/cli/daemon-cli/status.print.ts index 935941c1fe1..4f6f164db63 100644 --- a/src/cli/daemon-cli/status.print.ts +++ b/src/cli/daemon-cli/status.print.ts @@ -193,12 +193,12 @@ export function printDaemonStatus(status: DaemonStatus, opts: { json: boolean }) if (status.cli?.version && status.cli.version !== gatewayVersion) { defaultRuntime.error( warnText( - `Warning: CLI/runtime version skew detected. CLI is ${status.cli.version}; gateway is ${gatewayVersion}.`, + `Warning: this OpenClaw command is version ${status.cli.version}, but the running Gateway is version ${gatewayVersion}.`, ), ); defaultRuntime.error( warnText( - `Fix: check for stale PATH/global wrappers with \`command -v openclaw\`, \`readlink -f "$(command -v openclaw)"\`, and \`openclaw --version\`; reinstall the gateway service from the intended binary if needed.`, + "Check `openclaw --version`, `which openclaw`, and `openclaw gateway status --deep`; if this mismatch is unexpected, update PATH so `openclaw` points to the version you want, or reinstall the Gateway service from that same OpenClaw install.", ), ); } diff --git a/src/commands/doctor-gateway-health.test.ts b/src/commands/doctor-gateway-health.test.ts index 1b91be47b93..6b2ecd90abe 100644 --- a/src/commands/doctor-gateway-health.test.ts +++ b/src/commands/doctor-gateway-health.test.ts @@ -49,10 +49,10 @@ describe("checkGatewayHealth", () => { timeoutMs: 6000, }); expect(runtime.error).not.toHaveBeenCalled(); - expect(note).not.toHaveBeenCalledWith(expect.any(String), "Gateway version skew"); + expect(note).not.toHaveBeenCalledWith(expect.any(String), "OpenClaw version mismatch"); }); - it("notes CLI and gateway version skew when the gateway reports another runtime version", async () => { + it("notes CLI and gateway version mismatch when the gateway reports another runtime version", async () => { callGateway.mockResolvedValueOnce({ runtimeVersion: "2026.4.23" }).mockResolvedValueOnce({}); const runtime = { log: vi.fn(), error: vi.fn(), exit: vi.fn() }; @@ -61,12 +61,22 @@ describe("checkGatewayHealth", () => { ).resolves.toEqual({ healthOk: true, status: { runtimeVersion: "2026.4.23" } }); expect(note).toHaveBeenCalledWith( - expect.stringContaining("Gateway version: 2026.4.23"), - "Gateway version skew", + expect.stringContaining("the running Gateway is OpenClaw 2026.4.23"), + "OpenClaw version mismatch", ); expect(note).toHaveBeenCalledWith( - expect.stringContaining("stale global wrapper"), - "Gateway version skew", + expect.not.stringContaining("That usually means"), + "OpenClaw version mismatch", + ); + expect(note).toHaveBeenCalledWith( + expect.stringContaining("Check `openclaw --version`, `which openclaw`"), + "OpenClaw version mismatch", + ); + expect(note).toHaveBeenCalledWith( + expect.stringContaining( + "If this mismatch is unexpected, update PATH so `openclaw` points to the version you want", + ), + "OpenClaw version mismatch", ); }); diff --git a/src/commands/doctor-gateway-health.ts b/src/commands/doctor-gateway-health.ts index 77f222aac9e..160aca96388 100644 --- a/src/commands/doctor-gateway-health.ts +++ b/src/commands/doctor-gateway-health.ts @@ -33,12 +33,11 @@ function noteCliGatewayVersionSkew(status: StatusSummary | undefined): void { } note( [ - `CLI version: ${VERSION}`, - `Gateway version: ${gatewayVersion}`, - "The CLI and running gateway are different versions. This can happen when PATH points at a stale global wrapper while the service runs a newer install.", - 'Fix: run `openclaw gateway status --deep`; check `command -v openclaw`, `readlink -f "$(command -v openclaw)"`, and `openclaw --version`; reinstall the gateway service from the intended binary if needed.', + `This command is OpenClaw ${VERSION}; the running Gateway is OpenClaw ${gatewayVersion}.`, + "Check `openclaw --version`, `which openclaw`, and `openclaw gateway status --deep`.", + "If this mismatch is unexpected, update PATH so `openclaw` points to the version you want, or reinstall the Gateway service from that same OpenClaw install.", ].join("\n"), - "Gateway version skew", + "OpenClaw version mismatch", ); } diff --git a/src/config/io.compat.test.ts b/src/config/io.compat.test.ts index ae27ace465b..acc48a26aed 100644 --- a/src/config/io.compat.test.ts +++ b/src/config/io.compat.test.ts @@ -109,7 +109,7 @@ describe("config io paths", () => { }); }); - it("hints at stale wrappers when config was written by a newer OpenClaw", async () => { + it("explains what to check when config was written by a newer OpenClaw", async () => { await withTempHome(async (home) => { const configPath = path.join(home, ".openclaw", "openclaw.json"); await fs.mkdir(path.dirname(configPath), { recursive: true }); @@ -138,12 +138,19 @@ describe("config io paths", () => { io.loadConfig(); expect(logger.warn).toHaveBeenCalledWith( - expect.stringContaining("stale PATH or global wrappers"), + expect.stringContaining( + "Your OpenClaw config was written by version 9999.1.1, but this command is running", + ), ); - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining("command -v openclaw")); - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining("openclaw --version")); expect(logger.warn).toHaveBeenCalledWith( - expect.stringContaining("openclaw gateway status --deep"), + expect.stringContaining( + "Check: `openclaw --version`, `which openclaw`, and `openclaw gateway status --deep`.", + ), + ); + expect(logger.warn).toHaveBeenCalledWith( + expect.stringContaining( + "If unexpected, update PATH so `openclaw` points to the version you want", + ), ); }); }); diff --git a/src/config/io.ts b/src/config/io.ts index 5d4387051dc..f9daba9093d 100644 --- a/src/config/io.ts +++ b/src/config/io.ts @@ -908,9 +908,11 @@ function warnIfConfigFromFuture(cfg: OpenClawConfig, logger: Pick