fix(config): normalize gateway bind host aliases during migration (#30855)

* fix(config): normalize gateway bind host aliases during migration [AI-assisted]

* config(legacy): detect gateway.bind host aliases as legacy

* config(legacy): sanitize bind alias migration log output

* test(config): cover bind alias legacy detection and log escaping

* config(legacy): add source-literal gate to legacy rules

* config(legacy): make issue detection source-aware

* config(legacy): require source-literal gateway.bind alias detection

* config(io): pass parsed source to legacy issue detection

* test(config): cover resolved-only gateway.bind alias legacy detection

* changelog: format after #30855 rebase conflict resolution

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
Mark L
2026-03-02 11:53:00 +08:00
committed by GitHub
parent c9f0d6ac8e
commit 5b06c8c6e3
8 changed files with 202 additions and 10 deletions

View File

@@ -321,4 +321,51 @@ describe("config strict validation", () => {
expect(snap.legacyIssues).not.toHaveLength(0);
});
});
it("does not mark resolved-only gateway.bind aliases as auto-migratable legacy", async () => {
await withTempHome(async (home) => {
const configDir = path.join(home, ".openclaw");
await fs.mkdir(configDir, { recursive: true });
await fs.writeFile(
path.join(configDir, "openclaw.json"),
JSON.stringify({
gateway: { bind: "${OPENCLAW_BIND}" },
}),
"utf-8",
);
const prev = process.env.OPENCLAW_BIND;
process.env.OPENCLAW_BIND = "0.0.0.0";
try {
const snap = await readConfigFileSnapshot();
expect(snap.valid).toBe(false);
expect(snap.legacyIssues).toHaveLength(0);
expect(snap.issues.some((issue) => issue.path === "gateway.bind")).toBe(true);
} finally {
if (prev === undefined) {
delete process.env.OPENCLAW_BIND;
} else {
process.env.OPENCLAW_BIND = prev;
}
}
});
});
it("still marks literal gateway.bind host aliases as legacy", async () => {
await withTempHome(async (home) => {
const configDir = path.join(home, ".openclaw");
await fs.mkdir(configDir, { recursive: true });
await fs.writeFile(
path.join(configDir, "openclaw.json"),
JSON.stringify({
gateway: { bind: "0.0.0.0" },
}),
"utf-8",
);
const snap = await readConfigFileSnapshot();
expect(snap.valid).toBe(false);
expect(snap.legacyIssues.some((issue) => issue.path === "gateway.bind")).toBe(true);
});
});
});