diff --git a/src/config/paths.test.ts b/src/config/paths.test.ts index b72f7b37590..3ab428cc736 100644 --- a/src/config/paths.test.ts +++ b/src/config/paths.test.ts @@ -181,4 +181,20 @@ describe("resolveStateDir nesting guard (#45765)", () => { expect(resolveStateDir(env)).toBe(nestedDir); vi.restoreAllMocks(); }); + + it("preserves existing nested legacy dir when OPENCLAW_HOME ends in legacy basename", () => { + const env = { OPENCLAW_HOME: "/home/user/.clawdbot" } as NodeJS.ProcessEnv; + const nestedDir = path.resolve("/home/user/.clawdbot/.clawdbot"); + vi.spyOn(fsSync, "existsSync").mockImplementation((p) => String(p) === nestedDir); + expect(resolveStateDir(env)).toBe(nestedDir); + vi.restoreAllMocks(); + }); + + it("preserves nested .moldbot when OPENCLAW_HOME ends in .clawdbot", () => { + const env = { OPENCLAW_HOME: "/home/user/.clawdbot" } as NodeJS.ProcessEnv; + const nestedDir = path.resolve("/home/user/.clawdbot/.moldbot"); + vi.spyOn(fsSync, "existsSync").mockImplementation((p) => String(p) === nestedDir); + expect(resolveStateDir(env)).toBe(nestedDir); + vi.restoreAllMocks(); + }); }); diff --git a/src/config/paths.ts b/src/config/paths.ts index c35c3ffcf94..362c237f4ed 100644 --- a/src/config/paths.ts +++ b/src/config/paths.ts @@ -80,13 +80,16 @@ export function resolveStateDir( if (ALL_STATE_DIRNAMES.has(path.basename(resolvedHome))) { // Backward compat: if a nested state dir already exists from the old // buggy behavior, prefer it so we don't orphan existing state data. - const nestedState = path.join(resolvedHome, ".openclaw"); - try { - if (fs.existsSync(nestedState)) { - return nestedState; + // Check all known state dirnames, not just .openclaw. + for (const nestedName of ALL_STATE_DIRNAMES) { + const nestedState = path.join(resolvedHome, nestedName); + try { + if (fs.existsSync(nestedState)) { + return nestedState; + } + } catch { + // best-effort } - } catch { - // best-effort } return resolvedHome; }