Skip to content

Commit 4c3d1f8

Browse files
committed
fix: keep checkpoint persist no-op for malformed rows
1 parent d753604 commit 4c3d1f8

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

src/gateway/session-compaction-checkpoints.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,37 @@ describe("session-compaction-checkpoints", () => {
930930
expect(nextStore[MAIN_SESSION_KEY]?.compactionCheckpoints).toBeUndefined();
931931
});
932932

933+
test("persist skips malformed session rows without synthesizing a session id", async () => {
934+
const { storePath, sessionId, sessionKey, now } = await makeTempSessionStore(
935+
"openclaw-checkpoint-malformed-row-",
936+
);
937+
await writeSessionStore(storePath, sessionKey, {
938+
sessionId: "",
939+
updatedAt: now,
940+
});
941+
942+
const stored = await persistMainCheckpoint(storePath, {
943+
sessionId,
944+
snapshot: {
945+
sessionId,
946+
leafId: "pre-leaf",
947+
},
948+
postSessionFile: path.join(path.dirname(storePath), "sess.compacted.jsonl"),
949+
postLeafId: "post-leaf",
950+
createdAt: now,
951+
});
952+
953+
expect(stored).toBeNull();
954+
const nextStore = await readSessionStore<{
955+
compactionCheckpoints?: unknown[];
956+
sessionId?: string;
957+
}>(storePath);
958+
expect(nextStore[MAIN_SESSION_KEY]).toEqual({
959+
sessionId: "",
960+
updatedAt: now,
961+
});
962+
});
963+
933964
test("persist trims retained checkpoint snapshots by total byte budget", async () => {
934965
const { dir, storePath, sessionId, sessionKey, now } = await makeTempSessionStore(
935966
"openclaw-checkpoint-byte-trim-",

src/gateway/session-compaction-checkpoints.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,24 +779,29 @@ export async function persistSessionCompactionCheckpoint(
779779
removed: SessionCompactionCheckpoint[];
780780
}
781781
| undefined;
782+
let stored = false;
782783
const updatedEntry = await updateSessionEntry(
783784
{
784785
storePath: target.storePath,
785786
sessionKey: target.canonicalKey,
786787
},
787788
async (existing) => {
789+
if (!existing.sessionId) {
790+
return null;
791+
}
788792
const checkpoints = sessionStoreCheckpoints(existing);
789793
checkpoints.push(checkpoint);
790794
const snapshotBytesByPath = await statCheckpointSnapshotBytes(checkpoints);
791795
trimmedCheckpoints = trimSessionCheckpoints(checkpoints, snapshotBytesByPath);
796+
stored = true;
792797
return {
793798
updatedAt: Math.max(existing.updatedAt ?? 0, createdAt),
794799
compactionCheckpoints: trimmedCheckpoints.kept,
795800
};
796801
},
797802
);
798803

799-
if (!updatedEntry) {
804+
if (!updatedEntry || !stored) {
800805
log.warn("skipping compaction checkpoint persist: session not found", {
801806
sessionKey: params.sessionKey,
802807
});

0 commit comments

Comments
 (0)