Skip to content

fix(memory): drop per-search lastAccessed write causing Lance concurrent-writer errors#303

Merged
unohee merged 1 commit into
mainfrom
fix/memory-concurrent-write-access-time
Jul 16, 2026
Merged

fix(memory): drop per-search lastAccessed write causing Lance concurrent-writer errors#303
unohee merged 1 commit into
mainfrom
fix/memory-concurrent-write-access-time

Conversation

@unohee

@unohee unohee commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Problem

Running openswarm review --max --fix with many parallel reviewer subagents (up to 16) spammed:

[Memory] Failed to update access time: lance error: Too many concurrent writers.

Cause

searchMemorySafe (src/memory/memoryCore.ts) fired a Lance table.update() commit on every retrieval to stamp lastAccessed. With 16 concurrent reviewers each recalling memory, those commits collided on Lance's optimistic-concurrency retry limit.

Fix

Remove the write. lastAccessed has no read consumer — retrieval recency uses createdAt (access-frequency/decay was already removed, per the calculateFreshness comment), and no CLI surfaces the field (verified by grep across src/). So the per-search commit was pure contention with zero benefit. Dropped the call and the now-unused updateAccessTime helper. The schema field remains (set at record creation) so a batched/serialized decay writer can be reintroduced later if wanted.

Verification

  • npx tsc --noEmit — clean
  • npx vitest run src/memory/ — 32 pass
  • openswarm review — APPROVE (reviewer independently confirmed lastAccessed has 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

…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
unohee merged commit 49015cd into main Jul 16, 2026
5 checks passed
@unohee
unohee deleted the fix/memory-concurrent-write-access-time branch July 16, 2026 02:32
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.
@unohee unohee mentioned this pull request Jul 16, 2026
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.

1 participant