Skip to content

bug: Layer3.search_raw() in layers.py crashes on None metadata (same pattern as #1007) #1011

@bensig

Description

@bensig

Problem

`Layer3.search_raw()` in `mempalace/layers.py` has the same unguarded `meta.get(...)` pattern that #1007 / PR #999 fix in `searcher.py`. When ChromaDB's `query()` returns `None` for any metadata entry (partial-flush, mid-delete, schema upgrade boundaries), this path crashes with:

```
AttributeError: 'NoneType' object has no attribute 'get'
```

Where

`mempalace/layers.py`, around lines 300-341 — the `Layer3.search_raw` method iterates directly over `col.query(**kwargs)` results and calls `meta.get("wing", "unknown")`, `meta.get("room", "unknown")`, and `meta.get("source_file", "?")` without any null safety.

Root cause

Same as #1007: ChromaDB `query()` can return `None` in the `metadatas` list when a drawer's HNSW vector entry exists but its metadata row hasn't been materialized yet. #1006 documented this happens routinely on chromadb 1.5.x; even after the chromadb pin lands, partial-state results remain possible during interrupted mines or schema upgrades.

Proposed fix

Same two-line defensive coercion as #999 applies in `searcher.py`:

```diff
for i, (doc, meta, dist) in enumerate(zip(docs, metas, dists), 1):

  • meta = meta or {}
  • doc = doc or ""

    ... meta.get(...) calls that follow

```

Apply at the top of the results loop in `Layer3.search_raw()` so every downstream `meta.get()` and `doc.strip()` (or equivalent) is safe.

Relationship to other PRs

Good first issue

Small scope, established pattern (can copy from #999 / PR #1009 approach), self-contained in one file.

Why separate from #1007

Kept separate because `layers.py` is a different file with different test fixtures. PR #999 scoped itself to `searcher.py` + `miner.status()`; this is the third sibling that should land as a standalone PR to keep diffs reviewable.

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