LearnNewsExamplesServices
Frontmatter
id10934
titleFileSystemIngestor.spec flakes on shared GraphService SQLite-close under workers:1
stateClosed
labels
bugaitestingneeds-re-triage
assigneesneo-opus-4-7
createdAtMay 8, 2026, 12:06 AM
updatedAtMay 12, 2026, 4:10 AM
githubUrlhttps://github.com/neomjs/neo/issues/10934
authorneo-opus-4-7
commentsCount4
parentIssue10924
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 11, 2026, 1:08 AM

FileSystemIngestor.spec flakes on shared GraphService SQLite-close under workers:1

Closedbugaitestingneeds-re-triage
neo-opus-4-7
neo-opus-4-7 commented on May 8, 2026, 12:06 AM

Context

Surfaced 2026-05-08 during PR #10933 (Phase 3 unit-row re-add) CI run 25524203756. Test test/playwright/unit/ai/mcp/server/memory-core/services/FileSystemIngestor.spec.mjs:122 flakes with:

TypeError: The database connection is not open
   at SQLite.removeNodes (ai/graph/storage/SQLite.mjs:200)
   at Database.apply (ai/graph/Database.mjs:387)
   at Store.fire (src/core/Observable.mjs:255)
   at Store.splice (src/collection/Base.mjs:1608)
   at Store.clear (src/collection/Base.mjs:580)

Pass-on-retry, so doesn't break exit code by itself, but contributes to the flake count + cumulative test instability.

The Problem

FileSystemIngestor.spec.afterAll (line ~104-110) closes the singleton GraphService.db.storage.db and nulls GraphService.db. Under CI's workers:1 config (test/playwright/playwright.config.unit.mjs), all specs share one process — so any sibling spec that runs BEFORE FileSystemIngestor and ALSO closes the singleton in its own afterAll leaves GraphService.db in a zombie state. When the FileSystemIngestor test then tries to mutate via removeNodes, the underlying SQLite connection throws "not open".

This is a different shape than G5#2/G5#3 (which involve singleton-data pollution). G5-FSI is singleton-LIFECYCLE pollution — the singleton's connection is closed by a sibling.

The Architectural Reality

  • test/playwright/unit/ai/mcp/server/memory-core/services/FileSystemIngestor.spec.mjs:104-110 — afterAll closes GraphService.db.storage.db
  • ai/mcp/server/memory-core/services/GraphService.mjs — module-singleton; once closed, lazy re-init via _initPromise may not fire
  • ai/graph/storage/SQLite.mjs:200 removeNodes — naked this.db.prepare(...) with no defensive check on closed-connection state

The Fix (TBD via investigation)

Two candidate paths:

  1. Spec-level: refactor afterAll to NOT close shared singletons. Use beforeAll to ensure-init OR move to test.describe.configure({mode: 'serial'}) to bound the lifecycle.
  2. SDK-level: defensive this.db open-state check in SQLite.removeNodes (and sibling mutators) — gracefully no-op or self-heal via re-init.

Investigation needed before locking the prescription.

Acceptance Criteria

  • (AC1) Empirically reproduce the flake locally with workers:1 (matches CI substrate)
  • (AC2) Identify which sibling spec(s) close the singleton before FileSystemIngestor runs
  • (AC3) Implement chosen fix path (spec-level OR SDK-level)
  • (AC4) Verify FileSystemIngestor.spec runs deterministically across 5 consecutive npm run test-unit invocations on CI substrate

Out of Scope

  • Cross-spec singleton-lifecycle audit (separate epic-shaped concern; this ticket is the targeted fix for FileSystemIngestor specifically)
  • Migrating GraphService to per-test instances (too aggressive)

Avoided Traps

  • Skip-guard via NEO_TEST_SKIP_CI: deferred to here as the immediate ship-the-PR move on PR #10933, but NOT the proper fix. Skip preserves the gate-substrate value (no false-positive flake noise) while this investigation lands.
  • Increasing retries: 2 → 5: doesn't address the root cause; just papers over.
  • Disabling workers:1 in CI: that's a feature for deterministic singleton pollution detection, not a bug.

Related

  • Surfacing CI run: 25524203756 — PR #10933 unit suite (4 flakes + 999 passing)
  • Sibling state-pollution patterns: G5#2 (KBRecorderService — singleton-DATA pollution) + G5#3 (PermissionService — singleton-DATA pollution) per #10924 G5 triage
  • Substrate config: test/playwright/playwright.config.unit.mjs workers: 1 in CI

Origin Session ID: 7e897a0b-33ce-4d6c-b1a9-a1ff93e4e571

Retrieval Hint: query_raw_memories(query="FileSystemIngestor singleton SQLite close GraphService workers 1 flake PR 10933 CI run 25524203756")

tobiu referenced in commit 98897fc - "feat(ci): re-add unit suite to matrix post-Bucket-G substrate (#10939) (#10953) on May 8, 2026, 2:43 PM