fix(gateway): avoid Tailscale crash loops after upgrades (#126069)

* fix(gateway): migrate legacy Tailscale routes on upgrade

* fix(gateway): preserve unattributable Tailscale routes
This commit is contained in:
Josh Avant
2026-08-18 19:14:49 -05:00
committed by GitHub
parent fe816d69ef
commit 8d6cbee1b5
7 changed files with 157 additions and 0 deletions
@@ -2,6 +2,7 @@
import { createServer } from "node:http";
import { describe, expect, it, vi } from "vitest";
import { GatewayLockError } from "../../infra/gateway-lock.js";
import { TailscaleRouteOwnershipConflictError } from "../../infra/tailscale-route-ownership-error.js";
import { OpenClawAgentDatabaseMediaMigrationRequiredError } from "../../state/openclaw-agent-db-migration-required.js";
import { testing } from "./run.test-support.js";
@@ -21,6 +22,12 @@ function createLogger() {
}
describe("supervised gateway lock recovery", () => {
it("uses exit 78 for an ambiguous persistent Tailscale route", () => {
expect(
testing.resolveGatewayStartupFailureExitCode(new TailscaleRouteOwnershipConflictError()),
).toBe(78);
});
it("uses exit 78 for offline agent database migration requirements", () => {
expect(
testing.resolveGatewayStartupFailureExitCode(
+2
View File
@@ -55,6 +55,7 @@ import {
formatGatewayPidList,
} from "../../infra/gateway-processes.js";
import type { RespawnSupervisor } from "../../infra/supervisor-markers.js";
import { isTailscaleRouteOwnershipConflictError } from "../../infra/tailscale-route-ownership-error.js";
import { setConsoleSubsystemFilter, setConsoleTimestampPrefix } from "../../logging/console.js";
import { withDiagnosticPhase } from "../../logging/diagnostic-phase.js";
import { createSubsystemLogger } from "../../logging/subsystem.js";
@@ -478,6 +479,7 @@ function resolveGatewayLockErrorExitCode(err: unknown): number {
function resolveGatewayStartupFailureExitCode(err: unknown): number {
return isInvalidConfigError(err) ||
isTailscaleRouteOwnershipConflictError(err) ||
findOpenClawAgentDatabaseMediaMigrationRequiredError(err) ||
findOpenClawStateDatabaseSchemaMigrationRequiredError(err)
? EXIT_CONFIG_ERROR