Skip to content

Commit 36a233f

Browse files
committed
fix(config): honor isolated state-dir config writes
1 parent 51d6d70 commit 36a233f

2 files changed

Lines changed: 42 additions & 7 deletions

File tree

src/config/io.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {
3838
materializeRuntimeConfig,
3939
} from "./materialize.js";
4040
import { applyMergePatch } from "./merge-patch.js";
41-
import { resolveConfigPath, resolveDefaultConfigCandidates, resolveStateDir } from "./paths.js";
41+
import { resolveConfigPath, resolveStateDir } from "./paths.js";
4242
import { isBlockedObjectKey } from "./prototype-keys.js";
4343
import { applyConfigOverrides } from "./runtime-overrides.js";
4444
import type { OpenClawConfig, ConfigFileSnapshot, LegacyConfigIssue } from "./types.js";
@@ -1673,12 +1673,7 @@ async function finalizeReadConfigSnapshotInternalResult(
16731673

16741674
export function createConfigIO(overrides: ConfigIoDeps = {}) {
16751675
const deps = normalizeDeps(overrides);
1676-
const requestedConfigPath = resolveConfigPathForDeps(deps);
1677-
const candidatePaths = deps.configPath
1678-
? [requestedConfigPath]
1679-
: resolveDefaultConfigCandidates(deps.env, deps.homedir);
1680-
const configPath =
1681-
candidatePaths.find((candidate) => deps.fs.existsSync(candidate)) ?? requestedConfigPath;
1676+
const configPath = resolveConfigPathForDeps(deps);
16821677

16831678
function observeLoadConfigSnapshot(snapshot: ConfigFileSnapshot): ConfigFileSnapshot {
16841679
observeConfigSnapshotSync(deps, snapshot);

src/config/io.write-config.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,46 @@ describe("config io write", () => {
195195
},
196196
);
197197

198+
it("keeps writes inside an OPENCLAW_STATE_DIR override even when the real home config exists", async () => {
199+
await withSuiteHome(async (home) => {
200+
const liveConfigPath = path.join(home, ".openclaw", "openclaw.json");
201+
await fs.mkdir(path.dirname(liveConfigPath), { recursive: true });
202+
await fs.writeFile(
203+
liveConfigPath,
204+
`${JSON.stringify({ gateway: { mode: "local", port: 18789 } }, null, 2)}\n`,
205+
"utf-8",
206+
);
207+
208+
const overrideDir = path.join(home, "isolated-state");
209+
const env = { OPENCLAW_STATE_DIR: overrideDir } as NodeJS.ProcessEnv;
210+
const io = createConfigIO({
211+
env,
212+
homedir: () => home,
213+
logger: silentLogger,
214+
});
215+
216+
expect(io.configPath).toBe(path.join(overrideDir, "openclaw.json"));
217+
218+
await io.writeConfigFile({
219+
agents: { list: [{ id: "main", default: true }] },
220+
gateway: { mode: "local" },
221+
session: { mainKey: "main", store: path.join(overrideDir, "sessions.json") },
222+
});
223+
224+
const livePersisted = JSON.parse(await fs.readFile(liveConfigPath, "utf-8")) as {
225+
gateway?: { mode?: unknown; port?: unknown };
226+
};
227+
expect(livePersisted.gateway).toEqual({ mode: "local", port: 18789 });
228+
229+
const overridePersisted = JSON.parse(
230+
await fs.readFile(path.join(overrideDir, "openclaw.json"), "utf-8"),
231+
) as {
232+
session?: { store?: unknown };
233+
};
234+
expect(overridePersisted.session?.store).toBe(path.join(overrideDir, "sessions.json"));
235+
});
236+
});
237+
198238
it('shows actionable guidance for dmPolicy="open" without wildcard allowFrom', async () => {
199239
await withSuiteHome(async (home) => {
200240
const io = createConfigIO({

0 commit comments

Comments
 (0)