Skip to content

fix(memory): memoryFlush fires every compaction cycle instead of every other#1160

Open
BingqingLyu wants to merge 1 commit into
mainfrom
fork-pr-51421-fix-memoryflush-skip-every-other
Open

fix(memory): memoryFlush fires every compaction cycle instead of every other#1160
BingqingLyu wants to merge 1 commit into
mainfrom
fork-pr-51421-fix-memoryflush-skip-every-other

Conversation

@BingqingLyu

@BingqingLyu BingqingLyu commented Apr 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fixes memoryFlush only firing on alternating compaction cycles
  • One-line behavioral change: stop reassigning memoryFlushCompactionCount to the post-increment value

Root cause

After a memoryFlush during compaction, memoryFlushCompactionCount is reassigned to the post-increment compactionCount (line 536 of agent-runner-memory.ts). This locks both counters to the same value. On the next cycle, the dedup gate at reply-state.ts sees memoryFlushCompactionCount === compactionCount and skips the flush. Only after a regular compaction (without flush) increments compactionCount alone do the values differ again, allowing the next flush.

The result: flush, skip, flush, skip — memoryFlush fires on every other compaction instead of every one.

Fix

Remove the reassignment. memoryFlushCompactionCount stays at the pre-increment value (N). After incrementCompactionCount(), compactionCount becomes N+1. Next cycle, N !== N+1, flush fires. The counter is then updated through the normal session store update path.

-      const nextCount = await incrementCompactionCount({
+      await incrementCompactionCount({
         sessionEntry: activeSessionEntry,
         sessionStore: activeSessionStore,
         sessionKey: params.sessionKey,
         storePath: params.storePath,
       });
-      if (typeof nextCount === "number") {
-        memoryFlushCompactionCount = nextCount;
-      }
+      // Do NOT reassign memoryFlushCompactionCount to the post-increment value.
+      // Keeping it at the pre-increment value ensures the next compaction cycle
+      // sees different counters, allowing memoryFlush to fire every cycle
+      // instead of every other. See #12590.

Prior art

This issue has been reported and patch-attempted multiple times:

We've been running this fix as a local dist patch since early March 2026 with no issues.

Fixes openclaw#12590.

Test plan

  • Local patch running in production since 2026-03-08, no regressions
  • Existing reply-state.test.ts tests for memoryFlushCompactionCount logic pass
  • Change is minimal — removes a reassignment, adds a comment

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

…y other

After a memoryFlush during compaction, memoryFlushCompactionCount was
reassigned to the post-increment compactionCount, locking both counters
to the same value. The dedup gate hasAlreadyFlushedForCurrentCompaction
then saw equal values and skipped the next flush.

Fix: stop reassigning memoryFlushCompactionCount to the post-increment
value. The counter stays at N (pre-increment); after incrementCompactionCount,
compactionCount becomes N+1. Next cycle, N !== N+1, flush fires.

Closes openclaw#12590.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: memoryFlush does not fire reliably

2 participants