diff --git a/src/plugin-sdk/memory-host-events.test.ts b/src/plugin-sdk/memory-host-events.test.ts index f2569f8c2cb..3f2dad57adb 100644 --- a/src/plugin-sdk/memory-host-events.test.ts +++ b/src/plugin-sdk/memory-host-events.test.ts @@ -232,6 +232,20 @@ describe("createPersistentDedupe", () => { ]); }); + it("treats malformed legacy JSON cache files as empty", async () => { + const root = await createTempDir("openclaw-legacy-dedupe-malformed-"); + const legacyPath = path.join(root, "legacy.json"); + await fs.writeFile(legacyPath, "{not valid json"); + + await expect( + listPersistentDedupeLegacyJsonFileEntries({ + filePath: legacyPath, + ttlMs: 500, + now: 1_100, + }), + ).resolves.toStrictEqual([]); + }); + it("warms empty namespaces and ignores retired JSON cache files", async () => { const root = await createTempDir("openclaw-dedupe-"); const emptyReader = createDedupe(root, { ttlMs: 10_000 }); diff --git a/src/plugin-sdk/persistent-dedupe.ts b/src/plugin-sdk/persistent-dedupe.ts index 9e73ff3a7be..8231db8f800 100644 --- a/src/plugin-sdk/persistent-dedupe.ts +++ b/src/plugin-sdk/persistent-dedupe.ts @@ -326,7 +326,12 @@ function parseLegacyDedupeData(raw: string): { data: Record; invalidCount: number; } { - const parsed = JSON.parse(raw) as unknown; + let parsed: unknown; + try { + parsed = JSON.parse(raw) as unknown; + } catch { + return { data: {}, invalidCount: 0 }; + } if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { return { data: {}, invalidCount: 0 }; }