memdoctor
Memory corruption in AI agents is silent. The agent doesn't crash — it just starts remembering wrong.
memdoctor checks an agent's long-term memory store for the failure modes that quietly degrade it, and repairs the ones that can be repaired safely.
$ memdoctor check ./memory/
memdoctor v0.1.0 — sqlite backend
store ./memory/
memories 12480
vectors 12482
✗ D1 orphaned vectors..................... 4 found
ids: m09000, ghost-9912, ghost-9913
! D4 missing required fields.............. 2 found
ids: m00210, m00444
✗ D5 degenerate vectors................... 1 found
ids: m07741
7 issue(s) found in 0.4s. Run `memdoctor fix ./memory/` to repair.
fix quarantines what it removes before removing it, snapshots the store first, and never
touches memory content:
$ memdoctor fix ./memory/
memdoctor fix — sqlite backend
backup ./memory/memories.db.memdoctor-backup-2026-10-04T124003661024Z
quarantine ./memory/memories.db.memdoctor-quarantine.jsonl
removed orphaned_vector rowid=99001 id=ghost-9912 vector row has no matching memory row
removed degenerate_vector rowid=7742 id=m07741 embedding is all-zero, non-finite, or has zero norm
marked unembedded id=m07741 no vector remains; needs re-embedding
not automatically repairable:
orphaned_vector id=m09000 memory marked as embedded but has no embedding
The problem
Every agent framework now ships "long-term memory". Almost none of them ship a way to tell whether that memory is correct.
The failure modes are well documented in incident write-ups and are not the ones people expect:
- Orphaned vectors. The embedding write succeeds and the row write fails — or vice versa. Retrieval now returns memories that don't exist, or silently loses ones that do.
- Degenerate embeddings. A failed or rate-limited embed call persists a zero or NaN vector. That memory is now unreachable forever, and nothing warns you.
- Index divergence. The vector index and the source-of-truth store disagree, so
countin your logs has stopped matching reality. - Silent field rot. Rows missing content, timestamps or IDs that downstream code assumes are present.
- Poisoned memory. Adversarial or accidental writes that make the agent confident about things that are wrong.
None of these throw. The agent keeps answering. It just gets worse.
What it checks (v0.1)
Narrow on purpose — five detection classes, two backends:
| # | Check | Severity |
|---|---|---|
| D1 | Orphaned vectors (vector row without a memory row, or the reverse) | error |
| D2 | Duplicate or conflicting IDs | error |
| D3 | Embedding dimension mismatch against the store's declared dimension | error |
| D4 | Missing required fields (content, id, created_at) | warn |
| D5 | Degenerate vectors (all-zero, NaN, or non-finite) | error |
Usage
pip install memdoctor
memdoctor check ./memory/ # report only, never writes
memdoctor check ./memory/ --json # machine-readable, for CI
memdoctor fix ./memory/ # repair, backs up first
memdoctor fix ./memory/ --dry-run # show what would change
Design principles
- Report-only by default.
checknever writes.fixis explicit and always takes a backup first. - Safe repairs only. Orphans are removed, degenerate vectors are quarantined rather than deleted, and anything ambiguous is reported instead of guessed at.
- No dashboard, no daemon, no cloud. One command, one exit code — usable in a cron job or a CI pipeline.
- Narrow beats universal. Two backends done properly rather than eight done approximately.
Backends
| Backend | Status |
|---|---|
SQLite + sqlite-vec |
v0.1 |
| JSON / JSONL memory directory | v0.1 |
| Chroma, Qdrant, LanceDB, Letta, Mem0 | roadmap — issues welcome |
Status
v0.1, early. Built because running agent fleets in production makes this problem impossible to ignore — and because none of the memory frameworks diagnose or repair their own store.
Public domain — released under The Unlicense.
Contributing
If you have a corrupted memory store and a story about how it got that way, open an issue. The failure taxonomy is more useful than any single fix.
Metadata
Release files for memdoctor 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| memdoctor-0.1.0.tar.gz | 24.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| memdoctor-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.9 kB
Release files / memdoctor-0.1.0.tar.gz
| Download URL | memdoctor-0.1.0.tar.gz |
|---|---|
| Size | 24.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7922d48f9a3292092cf85afa8bc1dc06ea553a838390d15c60af1aa9705cc140
|
|
BLAKE2b-256 checksum How to use checksums |
f0681afb7c59d050854642ababffdfd3b4690c56b9b119eb3f0f5886b4dde1f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / memdoctor-0.1.0-py3-none-any.whl
| Download URL | memdoctor-0.1.0-py3-none-any.whl |
|---|---|
| Size | 21.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6025dc0ccc2435eeb9bbb2e17e7855ac03ec66f6e0b39facde882a03e29d621f
|
|
BLAKE2b-256 checksum How to use checksums |
642fdc66ba92a8a89c1a015ac8765952fe9b449c3bcc503cc2db7fba28317ab0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log