Skip to content

MemoryStore.recent(tags=...) silently drops tagged memories beyond a 10x fetch window #38

Description

@himanshu231204

Summary

MemoryStore.recent(limit, tags=...) silently drops tagged memories that fall outside a hard-coded 10× fetch window. A tagged memory can exist in the database and still be invisible to recent(tags=...).

Where

src/localmem_mcp/store.pyMemoryStore.recent() (lines 279–291)

rows = self._conn.execute(
    "SELECT * FROM memories ORDER BY id DESC LIMIT ?",
    (max(1, limit) * (10 if tag_list else 1),),
).fetchall()
memories = [_row_to_memory(row) for row in rows]
if tag_list:
    memories = [m for m in memories if _has_tags(m, tag_list)]
return memories[:limit]

The tag filter is applied in Python after fetching only the newest limit × 10 rows. Any tagged memory older than that window is never seen.

Reproduction

store.add("the tagged one", tags=["keep"])   # added FIRST (oldest)
for i in range(60):
    store.add(f"untagged memory {i}")        # 60 newer untagged memories

store.recent(limit=5, tags=["keep"])
# → []   (BUG: the tagged memory exists and should be returned)

Expected vs actual

  • Expected: recent(limit=5, tags=["keep"]) returns the tagged memory (docs promise "Only consider memories carrying all of these tags").
  • Actual: returns [] because the tagged row is at position 61, beyond the 5 × 10 = 50 row window.

Impact

The MCP recall_memory tool (no memory_id) and the CLI recall -n N --tag ... path both surface this: an agent asking for recent tagged memories can get an empty result even though matching memories exist. Silent data invisibility in a memory tool is worse than an error.

Suggested fix

Filter by tags in SQL (e.g. a LIKE/instr predicate on the comma-joined tags column, or a proper tag table), or loop fetching until limit tagged rows are collected. Add a regression test with the tagged memory older than limit × 10 untagged rows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: storageSQLite schema, persistence, migrationsbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions