diff --git a/src/utils.test.ts b/src/utils.test.ts index 4bb3b16422a..d9e9021de16 100644 --- a/src/utils.test.ts +++ b/src/utils.test.ts @@ -159,6 +159,18 @@ describe("resolveConfigDir", () => { const env = { OPENCLAW_HOME: "/srv/app" } as NodeJS.ProcessEnv; expect(resolveConfigDir(env)).toBe(path.resolve("/srv/app/.openclaw")); }); + + it("prefers existing nested config dir for backward compat (#45765)", () => { + const tmpDir = path.join(os.tmpdir(), `openclaw-test-config-${Date.now()}`); + const nestedDir = path.join(tmpDir, ".openclaw", ".openclaw"); + fs.mkdirSync(nestedDir, { recursive: true }); + try { + const env = { OPENCLAW_HOME: path.join(tmpDir, ".openclaw") } as NodeJS.ProcessEnv; + expect(resolveConfigDir(env)).toBe(path.join(tmpDir, ".openclaw", ".openclaw")); + } finally { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + }); }); describe("resolveHomeDir", () => { diff --git a/src/utils.ts b/src/utils.ts index 158e4ff080c..8b6ec7aab5c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -295,6 +295,16 @@ export function resolveConfigDir( const explicitHome = env.OPENCLAW_HOME?.trim(); const resolvedHome = resolveRequiredHomeDir(env, homedir); if (explicitHome && ALL_STATE_DIRNAMES.has(path.basename(resolvedHome))) { + // Backward compat: if a nested config dir already exists from the old + // buggy behavior, prefer it so we don't orphan existing config data. + const nestedConfig = path.join(resolvedHome, ".openclaw"); + try { + if (fs.existsSync(nestedConfig)) { + return nestedConfig; + } + } catch { + // best-effort + } return resolvedHome; } const newDir = path.join(resolvedHome, ".openclaw");