MemPalace/mempalace · error · MineValidationError
FTS5/SQLite quick_check failed: {len(errors)} issue(s)
Error message
FTS5/SQLite quick_check failed: {len(errors)} issue(s) What it means
Error "FTS5/SQLite quick_check failed: {len(errors)} issue(s)" thrown in MemPalace/mempalace.
Source
Thrown at mempalace/palace.py:1151
# Defer-import: keeps the repair module graph out of mine's hot import path.
from .repair import _close_chroma_handles, maybe_autoheal_fts5_index, sqlite_integrity_errors
# Pass the live singleton so the writer's cached PersistentClient actually
# gets closed and WAL flushes before the read-only sqlite3 re-open.
# A transient ChromaBackend (the default) would only clear its own empty
# `_clients` dict and leave _DEFAULT_BACKEND's live handle in place,
# which on Windows keeps the sqlite file mmap'd.
_close_chroma_handles(palace_path, backend=_DEFAULT_BACKEND)
errors = sqlite_integrity_errors(palace_path)
if errors:
# progress=logger.info, not the default print: this runs inside the
# MCP server process too (mcp_server.tool_mine -> miner.mine), where
# stdout is the JSON-RPC transport -- a stray print() here would
# corrupt the protocol stream and crash the connection.
errors = maybe_autoheal_fts5_index(palace_path, errors, progress=logger.info)
if errors:
raise MineValidationError(palace_path, errors)
# Process-wide record of palaces this PROCESS already holds the lock for. Used
# by `mine_palace_lock` to short-circuit re-entrant acquisition from the same
# process (e.g. miner.mine() acquires the outer lock then calls
# ChromaCollection.upsert which now also tries to acquire). Without this guard
# the inner call would block on its own outer flock (Linux fcntl locks are per
# open file description, so a second open of the lock file from the same process
# is a distinct lock and self-conflicts / EWOULDBLOCKs).
#
# This MUST be process-wide, not thread-local: the MCP HTTP transport
# (ThreadingHTTPServer) acquires the long-lived writer-lease on one thread
# (`mcp_server._acquire_mcp_writer_lock`) but dispatches each write request on a
# different worker thread. A thread-local guard makes those handlers fail to see
# the process-held lease, re-acquire the flock, and self-conflict
# ("palace ... is held by PID <self>"). flock is per-process and HTTP writes are
# serialized by `_HTTP_REQUEST_LOCK`, so the process is the correct re-entrancy
# boundary.View on GitHub (pinned to 06cb6987f0)
Solutions
- Run palace repair; restore from backup if quick_check keeps failing
When it happens
Trigger: Thrown at mempalace/palace.py:1151 when the library encounters an invalid state.
Common situations: SQLite FTS5 integrity check reported corruption.
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/64fc0a0287c49d51.
Report an issue: GitHub.