Skip to content

[Bug]: memory replace → "Multiple entries matched" → fallback add creates duplicate entries with no signal #60089

Description

@Vissirexa

Bug Description

MemoryStore.replace() refuses an ambiguous replace when old_text substring-matches two or more entries ("Multiple entries matched"), which is correct on its own. But when the model's intended replacement text is already present verbatim as a separate entry, that generic error sets a trap: the model's natural fallback is add(), which then creates a duplicate of the entry that already said what it wanted to write. The model never gets a signal that the fact it wanted to record already exists.

add() already guards the simpler case - exact duplicates are rejected with "Entry already exists (no duplicate added)", but the replace path gives no equivalent hint, so the duplicate arrives via the replace → add two-step.

Observed as a repeatable tool-misuse pattern running a local model (qwen3.6-35b) against the file memory store: replace → ambiguous match → fallback add → duplicate entry.

Steps to Reproduce

  1. Seed the file memory store with two entries sharing a substring (e.g. both containing "prefers dark mode") and a third entry whose text is exactly what the model would write as the update.
  2. Call memory(action="replace", old_text="prefers dark mode", new_content=<the third entry's exact text>).
  3. Get the generic "Multiple entries matched" error.
  4. Call memory(action="add", content=<same text>) with content differing even trivially from the existing entry (whitespace, punctuation), a duplicate is stored.

Expected Behavior

When an ambiguous replace's new_content already exists verbatim as a separate entry, the error should say so and point at a batch operations call to disambiguate instead of the generic ambiguity message, that invites a duplicate-creating add().

Actual Behavior

Generic "Multiple entries matched" error, then a duplicate entry after the fallback add.

Affected Component

Agent Core (conversation loop, context compression, memory)

Messaging Platform (if gateway-related)

No response

Debug Report

Not attaching "hermes debug share" links for this one: it's a code-level behavior
gap in tools/memory_tool.py, fully reproducible from unit tests and not
environment-specific, and my recent logs contain private gateway-session content.
Confirmed the gap still exists on current main by inspection — replace() returns
the generic ambiguity error with no check against existing entry content. Happy
to share specific redacted log excerpts on request.

System info (from "hermes debug share --local"):

version:      0.18.0 (2026.7.1)
os:           Darwin 25.4.0 arm64 (macOS 15, Apple Silicon)
python:       3.11.15
openai_sdk:   2.24.0
provider:     lmstudio (local OpenAI-compatible endpoint)
model:        Qwen3.6-35B-A3B-MLX-8bit
toolsets:     hermes-cli
memory:       built-in
gateway:      telegram

Operating System

macOS 15

Python Version

3.11.15

Hermes Version

0.18.0

Additional Logs / Traceback (optional)

Root Cause Analysis (optional)

No response

Proposed Fix (optional)

No response

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havearea/memoryMemory subsystem: store, providers, sync, background reviewsbugcomp/agentCore agent runtime: loop, agent_init, prompt builder, context-compression, responses endpointsweeper:risk-session-stateSweeper risk: may lose/corrupt/mis-associate session or context statetool/memoryMemory tool and memory providerstype/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions