Skip to content

fix: tool_add_drawer silently overwrites documents with shared 100-char prefix #715

@shafdev

Description

@shafdev

What happened?

tool_add_drawer generates the drawer ID by hashing only the first 100 characters of the content (content[:100]). Two documents in the same wing and room whose first 100 characters are identical are assigned the same drawer ID. When the second document is filed, it silently overwrites the first via upsert — no error, no warning, no indication that data was lost.

What did you expect?

Each document with distinct content should receive a unique drawer ID regardless of how similar the opening characters are. Filing a second document should never overwrite a different existing document.

How to reproduce:

  1. File a drawer with content that starts with a header longer than 100 characters (e.g. a company wiki template, Notion export, or meeting notes template)
  2. File a second drawer in the same wing and room whose content shares the same first 100 characters but differs after that
  3. Retrieve by the first drawer's ID — the original content is gone, replaced by the second document
import hashlib

wing, room = "work", "decisions"
header = "# ACME Corp Internal Knowledge Base\n**Project:** Alpha | **Team:** Backend | **Status:** Active\n\n"
doc1 = header + "Decision: Use PostgreSQL for primary storage."
doc2 = header + "Decision: Use Redis for session caching."

id1 = f"drawer_{wing}_{room}_{hashlib.sha256((wing + room + doc1[:100]).encode()).hexdigest()[:24]}"
id2 = f"drawer_{wing}_{room}_{hashlib.sha256((wing + room + doc2[:100]).encode()).hexdigest()[:24]}"
print(id1 == id2)  # True — data loss

Environment:

  • OS: macOS 15
  • Python version: 3.11.9
  • MemPalace version: 3.1.0 (commit 068dbd9)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/mcpMCP server and toolsarea/miningFile and conversation miningbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions