headroomlabs-ai/headroom · error · ValueError

Ambiguous ID ' '. Matches

Error message

Ambiguous ID '{memory_id}'. Matches: {[memory.id[:8] for memory in matches]}

What it means

When _resolve_memory's exact lookup misses but multiple stored memory IDs share the given prefix, it refuses to guess and raises ValueError listing the first 8 chars of every match. This is a deliberate unambiguity guarantee: prefix shortcuts must resolve to exactly one memory or the command aborts before mutating anything.

Solutions

  1. Extend the prefix until it matches exactly one ID listed in the error's Matches array
  2. Copy the full ID from `headroom memory list` output
  3. In scripts, never truncate IDs below the length that keeps them unique — store full IDs
  4. Prune/supersede old memories if ID collisions come from duplicate near-identical entries

Example fix

# before
$ headroom memory show 3f
# Ambiguous ID '3f'. Matches: ['3f9c1d2e', '3f77aa01']

# after
$ headroom memory show 3f9c1d2e4a5b6c7d
Defensive patterns

Strategy: validation

Validate before calling

import asyncio
from headroom.memory import MemoryFilter

def unique_prefix_ok(store, prefix: str) -> tuple[bool, int]:
    if asyncio.run(store.get(prefix)) is not None:
        return True, 1
    hits = [m for m in asyncio.run(store.query(MemoryFilter(limit=10000, include_superseded=True)))
            if m.id.startswith(prefix)]
    return len(hits) == 1, len(hits)

Try / catch

try:
    mem = _resolve_memory(store, memory_id)
except ValueError as e:
    if str(e).startswith("Ambiguous ID"):
        # message lists candidate 8-char prefixes — extend and retry
        candidates = parse_matches(str(e))
        raise SystemExit(f"extend prefix; candidates: {candidates}")
    raise

Prevention

When it happens

Trigger: Passing a short prefix (e.g. 2-4 hex chars) that is a prefix of several memory IDs, e.g. `headroom memory show 3f` when 3f9c1d2e... and 3f77aa01... both exist (superseded memories included).

Common situations: Users abbreviating long UUIDs too aggressively; DBs with many memories where random short prefixes collide; scripts truncating IDs to a fixed short width.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/a2e4f1a4cf8a643e. Report an issue: GitHub.

Appendix: source

Thrown at headroom/cli/memory.py:224

    except Exception as exc:
        print_warning(f"Vector index cleanup incomplete: {exc}")
        ok = False

    return ok


def _resolve_memory(store: SQLiteMemoryStore, memory_id: str) -> Memory:
    """Resolve an exact or unambiguous partial memory ID."""
    memory = asyncio.run(store.get(memory_id))
    if memory is not None:
        return memory

    memories = asyncio.run(store.query(MemoryFilter(limit=10000, include_superseded=True)))
    matches = [candidate for candidate in memories if candidate.id.startswith(memory_id)]
    if not matches:
        raise ValueError(f"Memory not found: {memory_id}")
    if len(matches) > 1:
        raise ValueError(
            f"Ambiguous ID '{memory_id}'. Matches: {[memory.id[:8] for memory in matches]}"
        )
    return matches[0]


async def _apply_supersession_repair(
    db_path: str,
    old_memory_id: str,
    new_memory_id: str,
    vector_dimension: int,
) -> tuple[Memory, Memory]:
    """Apply a repair through LocalBackend so indexes and cache are refreshed."""
    from ..memory.backends.local import LocalBackend, LocalBackendConfig

    backend = LocalBackend(
        LocalBackendConfig(
            db_path=db_path,
            vector_dimension=vector_dimension,

View on GitHub (pinned to 322425c43b)