Skip to content

fix(repair): coerce empty metadata sentinel in both rebuild paths (+ docs catch-up) - #28

Merged
jphein merged 2 commits into
mainfrom
fix/repair-meta-on-fork-main
May 11, 2026
Merged

jphein merged 2 commits into
mainfrom
fix/repair-meta-on-fork-main

Conversation

@jphein

@jphein jphein commented May 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two changes in one PR:

  1. Repair fix cherry-pick (commit 949cb20) — cherry-picks the parallel-agent commit 848774c from fix/repair-empty-metadata onto fork main. Fixes the chromadb-1.5.x ValueError: Expected metadata to be a non-empty dict at both _extract_drawers (~L139) and _rebuild_one_collection (~L816). Coerces None and empty-dict metadata to {"_repaired_empty_meta": True} — satisfies chromadb's validator AND is discoverable later via where= for operator audit. The _extract_drawers slice is in upstream PR #1459; the _rebuild_one_collection slice is fork-only for now.

  2. Doc-maintenance catch-up (commit cdee4dc) — Two YAML entries: repair-empty-meta-sentinel (carries pr: 1459) and hooks-routing-via-palace-daemon (for the 42ded2e commit from PR fix(hooks): route Stop/PreCompact through palace-daemon/clients/hook.py #27 earlier today). FORK_CHANGELOG regenerated. CLAUDE.md row 38 added for the hooks change (the repair entry is exempt via the pr: field).

Test plan

  • 67 test_repair tests pass (no regression from the both-locations coerce)
  • 43 corpus_origin / jargon-lint tests pass
  • scripts/check-docs.sh passes 5/5

🤖 Generated with Claude Code

jphein and others added 2 commits May 11, 2026 08:37
Two functions construct the metadatas[] list that gets fed to
chromadb's upsert/add, both vulnerable to the same ValueError:

  ValueError: Expected metadata to be a non-empty dict, got 0
  metadata attributes in add.

chromadb 1.5.x's validate_metadata rejects both `None` and `{}`
entries — see chromadb/api/types.py:validate_metadata (line ~1071).

This commit patches both:

1. `_extract_drawers` (line ~131) — the chromadb-collection-based
   extractor, used when the source palace's collection is openable
   via the chromadb client. Sanitizes None/{} entries in the
   `batch["metadatas"]` list to `{"_repaired_empty_meta": True}`
   before extending `all_metas`.

2. `_rebuild_one_collection` (line ~813) — the SQLite-direct
   extract path used by `rebuild_from_sqlite()`, invoked when the
   source palace can't be opened via chromadb (the recovery path
   for palaces with corrupt HNSW segments). Old code was:

       metas.append(meta if meta else {})

   The trailing `{}` was the bug; chromadb 1.5.x rejects empty
   dicts the same as None. Replaced with the same sentinel.

Why `_repaired_empty_meta: True` as the sentinel:
  - Satisfies chromadb's non-empty-dict requirement
  - Bool-valued (valid chromadb metadata type, trivially serializable)
  - Namespaced + descriptive so an operator can find which drawers
    were coerced via `where={"_repaired_empty_meta": True}` later
  - Idempotent on re-runs (a future repair over a sanitized palace
    sees the sentinel as already-valid)

Verified on a 151,478-drawer production palace that previously
crashed at drawer 120,000 in both extract paths.

Fixes MemPalace#1458

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two YAML entries added (newest first):
- `repair-empty-meta-sentinel` (commit `949cb20`, cherry-pick of
  jp/parallel-agent's `848774c`): both-locations fix for the
  metadata-sanitization bug class. Carries `pr: 1459` for the
  upstream slice; the YAML body documents the fork-only portion
  (`_rebuild_one_collection`).
- `hooks-routing-via-palace-daemon` (commit `42ded2e`, already on
  main since PR #27 earlier today): the Stop/PreCompact routing
  change to palace-daemon's hook client. No `pr:` — fork-only
  deployment config with absolute paths.

FORK_CHANGELOG.md regenerated from the updated YAML. CLAUDE.md row
38 added for the hooks change (the repair entry is exempt from row
inventory via `pr: 1459`). `scripts/check-docs.sh` passes 5/5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 11, 2026 15:43
@jphein
jphein merged commit 60f62f4 into main May 11, 2026
@jphein
jphein deleted the fix/repair-meta-on-fork-main branch May 11, 2026 15:43
@jphein
jphein removed the request for review from Copilot May 11, 2026 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant