fix: preserve deleted main-store ownership

This commit is contained in:
Gustavo Madeira Santana
2026-04-19 18:13:04 -04:00
parent c79a5f324e
commit 8e8d5ce530
2 changed files with 59 additions and 4 deletions

View File

@@ -34,11 +34,16 @@ function resolveDefaultStoreAgentId(cfg: OpenClawConfig): string {
function shouldRemapLegacyDefaultMainAlias(
cfg: OpenClawConfig,
parsed: ParsedAgentSessionKey,
options?: { storeAgentId?: string },
): boolean {
const agentId = normalizeAgentId(parsed.agentId);
if (agentId !== DEFAULT_AGENT_ID || listAgentIds(cfg).includes(DEFAULT_AGENT_ID)) {
return false;
}
const defaultAgentId = resolveDefaultStoreAgentId(cfg);
if (options?.storeAgentId && normalizeAgentId(options.storeAgentId) !== defaultAgentId) {
return false;
}
const rest = normalizeLowercaseStringOrEmpty(parsed.rest);
const mainKey = normalizeMainKey(cfg.session?.mainKey);
return rest === "main" || rest === mainKey;
@@ -48,8 +53,9 @@ function resolveParsedSessionStoreKey(
cfg: OpenClawConfig,
raw: string,
parsed: ParsedAgentSessionKey,
options?: { storeAgentId?: string },
): { agentId: string; sessionKey: string } {
if (!shouldRemapLegacyDefaultMainAlias(cfg, parsed)) {
if (!shouldRemapLegacyDefaultMainAlias(cfg, parsed, options)) {
return {
agentId: normalizeAgentId(parsed.agentId),
sessionKey: normalizeLowercaseStringOrEmpty(raw),
@@ -63,6 +69,7 @@ function resolveParsedSessionStoreKey(
export function resolveSessionStoreKey(params: {
cfg: OpenClawConfig;
sessionKey: string;
storeAgentId?: string;
}): string {
const raw = normalizeOptionalString(params.sessionKey) ?? "";
if (!raw) {
@@ -75,7 +82,9 @@ export function resolveSessionStoreKey(params: {
const parsed = parseAgentSessionKey(raw);
if (parsed) {
const resolved = resolveParsedSessionStoreKey(params.cfg, raw, parsed);
const resolved = resolveParsedSessionStoreKey(params.cfg, raw, parsed, {
storeAgentId: params.storeAgentId,
});
const canonical = canonicalizeMainSessionAlias({
cfg: params.cfg,
agentId: resolved.agentId,
@@ -121,7 +130,11 @@ export function resolveStoredSessionKeyForAgentStore(params: {
return lowered;
}
const key = parseAgentSessionKey(raw) ? raw : canonicalizeSessionKeyForAgent(params.agentId, raw);
return resolveSessionStoreKey({ cfg: params.cfg, sessionKey: key });
return resolveSessionStoreKey({
cfg: params.cfg,
sessionKey: key,
storeAgentId: params.agentId,
});
}
export function resolveStoredSessionOwnerAgentId(params: {

View File

@@ -1,6 +1,6 @@
import path from "node:path";
import { describe, expect, it } from "vitest";
import { saveSessionStore } from "../config/sessions.js";
import { resolveStorePath, saveSessionStore } from "../config/sessions.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { withStateDirEnv } from "../test-helpers/state-dir-env.js";
import { ErrorCodes } from "./protocol/index.js";
@@ -67,4 +67,46 @@ describe("resolveSessionKeyFromResolveParams store canonicalization", () => {
});
});
});
it("does not adopt legacy main aliases from discovered deleted-agent stores", async () => {
await withStateDirEnv("openclaw-sessions-resolve-discovered-main-", async () => {
const cfg: OpenClawConfig = {
agents: { list: [{ id: "ops", default: true }] },
};
const staleMainStorePath = resolveStorePath(cfg.session?.store, { agentId: "main" });
await saveSessionStore(staleMainStorePath, {
"agent:main:main": {
sessionId: "sess-discovered-main",
label: "discovered-main",
updatedAt: 1,
},
});
await expect(
resolveSessionKeyFromResolveParams({
cfg,
p: { sessionId: "sess-discovered-main" },
}),
).resolves.toEqual({
ok: false,
error: {
code: ErrorCodes.INVALID_REQUEST,
message: 'Agent "main" no longer exists in configuration',
},
});
await expect(
resolveSessionKeyFromResolveParams({
cfg,
p: { label: "discovered-main" },
}),
).resolves.toEqual({
ok: false,
error: {
code: ErrorCodes.INVALID_REQUEST,
message: 'Agent "main" no longer exists in configuration',
},
});
});
});
});