LearnNewsExamplesServices
Frontmatter
id13464
titleRecover KB MCP from stale Chroma collection handles
stateClosed
labels
bugairegressionarchitecturemodel-experience
assigneesneo-gpt
createdAtJun 18, 2026, 11:34 AM
updatedAtJun 18, 2026, 11:58 AM
githubUrlhttps://github.com/neomjs/neo/issues/13464
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 18, 2026, 11:58 AM

Recover KB MCP from stale Chroma collection handles

Closed v13.1.0/archive-v13-1-0-chunk-3 bugairegressionarchitecturemodel-experience
neo-gpt
neo-gpt commented on Jun 18, 2026, 11:34 AM

Context

The Knowledge Base MCP surface is again in the failure shape previously narrowed in #12944: the canonical Chroma daemon is reachable, Memory Core is healthy against the same unified store, but the KB MCP runtime reports collections.knowledgeBase: null and gates KB read tools.

Live evidence from 2026-06-18T09:19Z-09:23Z:

  • mcp__neo_mjs_memory_core.healthcheck() returned status: "healthy", database.process.running: false, database.connection.connected: true, and collection counts for neo-agent-memory and neo-agent-sessions.
  • mcp__neo_mjs_knowledge_base.healthcheck() returned status: "unhealthy", database.process.running: false, database.connection.connected: true, collections.knowledgeBase: null, and details: ["Failed to access collections: The requested resource could not be found"].
  • mcp__neo_mjs_knowledge_base.list_documents({limit:1}) and ask_knowledge_base(...) both failed through the health gate with the same missing-collection detail.

This ticket deliberately does not restore or investigate the KB corpus itself. That is a separate follow-up lane. This ticket targets the durable MCP/runtime contract gap exposed when a long-lived KB MCP process holds a stale or operation-failing collection handle under the unified Chroma topology.

Release classification: boardless — Agent OS hardening, not a v13 release-blocker.

The Problem

The KB MCP health/gate path collapses several states into unhealthy and has no self-healing path for a successfully resolved collection handle that later fails on an operation:

  • ai/services/knowledge-base/HealthService.mjs:202-204 resolves the KB collection and then calls count().
  • ai/services/knowledge-base/HealthService.mjs:219-223 catches count()/collection operation errors and returns Failed to access collections, but it does not invalidate the cached KB collection handle or retry once.
  • ai/services/knowledge-base/HealthService.mjs:315-324 turns collection errors or missing collection state into unhealthy before embedding/provider readiness is checked, so features.embedding:false can be a misleading short-circuit artifact.
  • ai/services/knowledge-base/HealthService.mjs:448-455 rejects every non-exempt KB tool unless the whole healthcheck is healthy.
  • ai/mcp/server/knowledge-base/Server.mjs:75-77 only exempts healthcheck and list_agent_faqs; manage_knowledge_base is health-gated, so the MCP surface can block the likely recovery path.
  • ai/mcp/server/knowledge-base/Server.mjs:131-134 still emits a local chroma run hint when process.running:false, even though unified topology expects KB to connect to an orchestrator-managed daemon, matching MC's healthy process.running:false shape.

#12944 closed after the corpus was restored and a Codex KB MCP restart made the runtime healthy again. Its final closeout explicitly left this durable follow-up separate: operation-failure invalidation/retry or cross-process invalidation for a successfully resolved KB collection handle after shadow-swap.

The Architectural Reality

ADR 0003 and ADR 0017 define one Chroma daemon / one flat unified store, with realm separation by collection. In current local operation, the relevant collections remain separate: neo-agent-memory, neo-agent-sessions, and neo-knowledge-base.

Memory Core already reports the unified-daemon shape correctly: process.running:false can still be healthy when connection.connected:true and required collections are accessible. KB should use the same topology semantics while keeping corpus readiness distinct from daemon connectivity.

ai/services/knowledge-base/ChromaManager.mjs:114-127 already invalidates the memoized collection promise when collection resolution throws. The missing durable behavior is at operation sites: a resolved collection handle can go stale or become invalid after a shadow-swap / restore / process boundary, and count() or query operations can then throw not-found without clearing the successful cached handle.

The Fix

Implement a narrow KB MCP hardening pass:

  1. Add operation-failure invalidation/retry around KB collection operations that use a resolved collection handle, starting with the healthcheck count() path.
  2. Classify KB healthcheck output so it separates:
    • Chroma connectivity (connection.connected),
    • KB corpus readiness (collections.knowledgeBase.exists/count/error or an equivalent explicit corpus block),
    • embedding/provider readiness.
  3. Make startup/status messaging unified-topology aware: do not tell operators to start a local Chroma process solely because process.running:false when the server is connected to orchestrator-owned Chroma.
  4. Let manage_knowledge_base reach the recovery/sync path under a weaker gate where Chroma/provider prerequisites are sufficient, instead of requiring the corpus collection to already be healthy.
  5. Add focused unit coverage for the stale-handle path and gate classification. Do not run default Playwright; use npm run test-unit -- <specific ai specs>.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
KnowledgeBase HealthService.healthcheck() payload ADR 0003, ADR 0017, current MC healthcheck precedent Reports connected orchestrator-owned Chroma separately from KB corpus readiness and provider readiness. A missing or operation-failing neo-knowledge-base collection is explicit degraded/corpus-unavailable state, not a misleading daemon outage. JSDoc/update inline status comments if status semantics change. Focused KB HealthService unit tests covering connected Chroma + missing/stale corpus handle.
KnowledgeBase ChromaManager.invalidateKnowledgeBaseCollectionCache() usage ai/services/knowledge-base/ChromaManager.mjs:258-261 Operation-level not-found on a resolved KB collection invalidates the cached handle and retries once where safe. If retry also fails, healthcheck reports the corpus error without hanging; query/list tools stay unavailable. JSDoc for the retry/invalidation helper or call-site comment. Unit test with first count() throwing not-found, cache invalidated, second resolution succeeds.
KB MCP health gate for manage_knowledge_base ai/mcp/server/knowledge-base/Server.mjs:75-77; BaseServer health gate Recovery/sync/embed can run when Chroma/provider prerequisites are available even if corpus readiness is false. Destructive delete remains guarded by existing destructive-operation protections; read/query tools remain blocked when corpus unavailable. Tool/server comments if exemption or gate split changes. MCP/server unit or focused service test showing manage_knowledge_base is not blocked solely by missing corpus.
KB startup logging ADR 0003/0017 unified Chroma topology process.running:false is described as external/orchestrator-managed when connection.connected:true. Only emit start-local-Chroma guidance when connection is false. Update log message text only. Unit test or focused projection test for startup status logging, plus manual healthcheck output.

Decision Record impact

Aligned with ADR 0003 and ADR 0017. This ticket does not amend either ADR; it brings KB diagnostics and gating in line with their unified-Chroma topology.

Acceptance Criteria

  • With Chroma connected and KB collection count() throwing a Chroma not-found/resource-not-found error on the first resolved handle, KB healthcheck invalidates the cached handle and retries once before reporting failure.
  • KB healthcheck does not label connected orchestrator-owned Chroma as a local-daemon outage solely because database.process.running === false.
  • KB healthcheck output distinguishes Chroma connectivity from KB corpus readiness and embedding/provider readiness; features.embedding:false is not used as a misleading short-circuit when the provider was not checked.
  • manage_knowledge_base recovery actions are not blocked solely because the current KB corpus collection is missing/unreachable, while read/query tools still fail clearly until the corpus is available.
  • Focused unit coverage proves the stale-handle recovery and gate-classification behavior.

Out of Scope

  • Restoring or rebuilding the KB corpus collection.
  • Investigating why the current local neo-knowledge-base collection is missing or unreachable.
  • Reworking the shadow-swap architecture or adding a cross-process invalidation bus.
  • Changing Memory Core collection semantics.
  • Running a full KB ingest as part of this ticket.

Related

  • Related: #12944
  • ADR 0003: learn/agentos/decisions/0003-chroma-topology-unified-only.md
  • ADR 0017: learn/agentos/decisions/0017-chroma-single-flat-unified-store.md
  • Discussion context: #11677

Duplicate Sweep

  • Live latest-open sweep: checked latest 20 open issues at 2026-06-18T09:33:54Z; no equivalent open ticket found.
  • A2A latest-30 sweep: no overlapping recent [lane-claim] / [lane-intent] found for KB healthcheck/stale-collection-handle work.
  • Scoped live GitHub search for stale collection handle KB healthcheck operation failure invalidation retry returned only closed #12944.
  • Local exact sweep over resources/content/issues and resources/content/discussions found closed #12944 plus #11677 discussion context, not an active implementation ticket.
  • KB semantic sweep attempted with ask_knowledge_base(query='tickets about KB stale Chroma collection handle operation failure invalidation retry healthcheck manage_knowledge_base', type='ticket') and failed because the KB MCP is currently unavailable; this ticket does not rely on KB silence.

Origin Session ID: 4ce60429-2986-4543-be2d-741957c75b6c

Retrieval Hint: query_raw_memories("KB healthcheck Memory Core healthcheck unified Chroma missing knowledge-base collection healthy degraded") Retrieval Hint: query_raw_memories("stale successfully resolved KB collection handle operation failure invalidation retry shadow-swap")

tobiu referenced in commit 520dc4a - "fix(ai): recover KB stale collection handles (#13464) (#13465)" on Jun 18, 2026, 11:58 AM
tobiu closed this issue on Jun 18, 2026, 11:58 AM