From 66a4410095d4e4e6406f1ccfee514983bf1b77ca Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 30 May 2026 18:20:56 -0400 Subject: [PATCH] fix(memory): bound session export timestamps --- .../src/host/session-files.test.ts | 18 ++++++++++++++++++ .../memory-host-sdk/src/host/session-files.ts | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/memory-host-sdk/src/host/session-files.test.ts b/packages/memory-host-sdk/src/host/session-files.test.ts index 6685789b1d0..66d9e96c826 100644 --- a/packages/memory-host-sdk/src/host/session-files.test.ts +++ b/packages/memory-host-sdk/src/host/session-files.test.ts @@ -295,4 +295,22 @@ describe("buildSessionEntry", () => { expect(entry.content).toBe("Assistant: User-facing summary.\nUser: Actual user follow-up."); expect(entry.lineMap).toStrictEqual([2, 3]); }); + + it("drops Date-invalid numeric message timestamps", async () => { + const jsonlLines = [ + JSON.stringify({ + type: "message", + message: { + role: "user", + content: "Hello", + timestamp: 8_640_000_000_000_001, + }, + }), + ]; + const filePath = path.join(tmpDir, "invalid-timestamp-session.jsonl"); + fsSync.writeFileSync(filePath, jsonlLines.join("\n")); + + const entry = requireSessionEntry(await buildSessionEntry(filePath)); + expect(entry.messageTimestampsMs).toStrictEqual([0]); + }); }); diff --git a/packages/memory-host-sdk/src/host/session-files.ts b/packages/memory-host-sdk/src/host/session-files.ts index fec2a4bab0c..bbe84a5a392 100644 --- a/packages/memory-host-sdk/src/host/session-files.ts +++ b/packages/memory-host-sdk/src/host/session-files.ts @@ -28,6 +28,7 @@ const DREAMING_NARRATIVE_RUN_PREFIX = "dreaming-narrative-"; // This limit applies to content only; the role label adds up to 11 chars. const SESSION_EXPORT_CONTENT_WRAP_CHARS = 800; const SESSION_ENTRY_PARSE_YIELD_LINES = 250; +const MAX_DATE_TIMESTAMP_MS = 8_640_000_000_000_000; const DIRECT_CRON_PROMPT_RE = /^\[cron:[^\]]+\]\s*/; export type SessionFileEntry = { @@ -509,7 +510,7 @@ function parseSessionTimestampMs( for (const value of candidates) { if (typeof value === "number" && Number.isFinite(value)) { const ms = value > 0 && value < 1e11 ? value * 1000 : value; - if (Number.isFinite(ms) && ms > 0) { + if (Number.isFinite(ms) && ms > 0 && ms <= MAX_DATE_TIMESTAMP_MS) { return ms; } }