fix(memory): drop per-search lastAccessed write causing Lance concurrent-writer errors#303
Merged
Merged
Conversation
…current-writer errors searchMemorySafe fired a Lance table.update() on every retrieval to stamp lastAccessed. Under 'openswarm review --max' (up to 16 concurrent reviewer subagents each recalling memory) those commits collided on Lance's optimistic- concurrency retry limit → 'Too many concurrent writers … [Memory] Failed to update access time'. lastAccessed has no read consumer: retrieval recency uses createdAt (access-frequency/decay was already removed) and no CLI surfaces it, so the write was pure contention with zero benefit. Remove it (and the now-unused updateAccessTime helper). The schema field stays, set at record creation, so a batched/serialized decay writer can be reintroduced later if needed.
unohee
added a commit
that referenced
this pull request
Jul 16, 2026
…INT-2817) (#304) The lastAccessed fix (#303) removed the per-search write, but the store path (table.add) and predicated update/delete can still collide under 'openswarm review --max' — up to 16 reviewer subagents are SEPARATE processes sharing one on-disk Lance table, and Lance's built-in commit-retry budget (~2 attempts/30s) is too small for that fan-out. An in-process mutex can't help across processes, so wrap every memory write in withMemoryWriteRetry: retry on optimistic-concurrency conflicts with exponential backoff + full jitter (max 8 attempts) so racing writers desynchronize and re-commit against the latest version. Applied to all 5 write sites (add x2, delete x2, update x1). Non- retryable errors rethrow immediately; matcher kept tight to real conflict signals.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Running
openswarm review --max --fixwith many parallel reviewer subagents (up to 16) spammed:Cause
searchMemorySafe(src/memory/memoryCore.ts) fired a Lancetable.update()commit on every retrieval to stamplastAccessed. With 16 concurrent reviewers each recalling memory, those commits collided on Lance's optimistic-concurrency retry limit.Fix
Remove the write.
lastAccessedhas no read consumer — retrieval recency usescreatedAt(access-frequency/decay was already removed, per thecalculateFreshnesscomment), and no CLI surfaces the field (verified by grep acrosssrc/). So the per-search commit was pure contention with zero benefit. Dropped the call and the now-unusedupdateAccessTimehelper. The schema field remains (set at record creation) so a batched/serialized decay writer can be reintroduced later if wanted.Verification
npx tsc --noEmit— cleannpx vitest run src/memory/— 32 passopenswarm review— APPROVE (reviewer independently confirmedlastAccessedhas no active read consumer, incl.memoryOps.ts)Residual note
Concurrent
table.add()on the store path could in principle contend too, but that wasn't the reported failure (reviewers mostly recall). Left in scope-tight; can be hardened separately if it surfaces.🤖 Generated with Claude Code