Skip to content

bug: mempalace search crashes with AttributeError: 'NoneType' object has no attribute 'get' on partial-state results (searcher.py:286) #1007

@bensig

Description

@bensig

Problem

`mempalace search ` raises `AttributeError: 'NoneType' object has no attribute 'get'` whenever a ChromaDB query result contains a `None` metadata entry. The reader assumes `meta` is always a dict; it isn't.

Traceback

Traceback (most recent call last):
  File "mempalace/cli.py", line 681, in main
    dispatch[args.command](args)
  File "mempalace/cli.py", line 153, in cmd_search
    search(query=args.query, ..., n_results=args.results)
  File "mempalace/searcher.py", line 286, in search
    source = Path(meta.get("source_file", "?")).name
             ^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

When this happens

Any ChromaDB state where `query()` returns `[None]` for one or more results:

Even after #1006's chromadb pin lands, these edge cases remain. Defensive reads are cheap.

Current code

`mempalace/searcher.py:284-288`:

for i, (doc, meta, dist) in enumerate(zip(docs, metas, dists), 1):
    similarity = round(max(0.0, 1 - dist), 3)
    source = Path(meta.get("source_file", "?")).name
    wing_name = meta.get("wing", "?")
    room_name = meta.get("room", "?")

Line 295 further down does `doc.strip()` which has the same `None` vulnerability.

Proposed fix

 for i, (doc, meta, dist) in enumerate(zip(docs, metas, dists), 1):
     similarity = round(max(0.0, 1 - dist), 3)
+    meta = meta or {}
+    doc = doc or ""
     source = Path(meta.get("source_file", "?")).name
     wing_name = meta.get("wing", "?")
     room_name = meta.get("room", "?")

Two-line defensive guard. Degrades gracefully: source shows `"?"`, wing/room show `"?"`, the document body prints empty. The hit still appears in results (with distance/index), which is more useful than crashing.

Worth considering: should a `None`-metadata result be filtered out entirely rather than shown with placeholders? Argument for showing: distances are real, user may want to see that results exist even if storage is partial. Argument for filtering: empty rows look broken. Either decision is fine — crashing is not.

Test idea

Add a regression test that mocks a ChromaDB query returning `{"documents": [[None]], "metadatas": [[None]], "distances": [[0.5]], "ids": [["x"]]}` and confirms `search()` completes without raising. Simple, targeted, cheap.

Good first issue

Small scope, clear fix, obvious test.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/searchSearch and retrievalbugSomething isn't workinggood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions