fix: resolve normalized account IDs before token-override checks

When normalizeAccountId transforms config keys (e.g. 'Router D' →
'router-d'), listAccountIds returns normalized IDs but the
everyAccountHasOwnTokens check used accounts[normalizedId], which
misses the raw config key. Added a reverse map from normalized ID
to raw key for the lookup.

Regression test: non-canonical key normalizes correctly and default
is still injected when the account has its own tokens.
This commit is contained in:
zeroaltitude 2026-03-08 00:29:12 -07:00
parent 4e626e91db
commit 86cc78d593
No known key found for this signature in database
GPG Key ID: 77592FB1C703882E
2 changed files with 30 additions and 1 deletions

View File

@ -95,6 +95,24 @@ describe("createAccountListHelpers", () => {
expect(listAccountIds(config)).toEqual(["default", "tank"]);
});
it("includes default when normalized IDs differ from raw config keys", () => {
const normalizedHelpers = createAccountListHelpers("testchannel", {
normalizeAccountId: (id: string) => id.toLowerCase().replace(/\s+/g, "-"),
});
const config = {
channels: {
testchannel: {
botToken: "xoxb-base",
accounts: {
"Router D": { botToken: "xoxb-router-d" },
},
},
},
} as unknown as OpenClawConfig;
// "Router D" normalizes to "router-d" — should still detect own token
expect(normalizedHelpers.listAccountIds(config)).toEqual(["default", "router-d"]);
});
it("does NOT inject default in mixed configs (some accounts inherit base tokens)", () => {
const config = {
channels: {

View File

@ -63,8 +63,19 @@ export function createAccountListHelpers(
);
if (baseTokenFields.length > 0) {
const accounts = (base?.accounts ?? {}) as Record<string, Record<string, unknown>>;
// Build reverse map from normalized ID → raw config key so we can look
// up the account object even when normalizeAccountId transforms the keys.
const rawKeys = Object.keys(accounts);
const normalizedToRaw = new Map<string, string>();
for (const key of rawKeys) {
const normalized = normalizeAccountId(key);
if (normalized && !normalizedToRaw.has(normalized)) {
normalizedToRaw.set(normalized, key);
}
}
const everyAccountHasOwnTokens = ids.every((id) => {
const acct = accounts[id];
const rawKey = normalizedToRaw.get(id) ?? id;
const acct = accounts[rawKey];
if (!acct) {
return false;
}