Skip to content

PDF indexing can crash if you switch projects while it's still running #38

Description

@inactinique

Summary

Switching ClioDeck projects while a PDF is still being indexed can crash the in-flight indexing job: pdf-service.ts's init(projectPath), called on every project switch, unconditionally closes the previous project's vectorStore — including while an indexing operation for that project is still running and expects to write to it.

Found while auditing the ClioDeck wiki against the actual code (pass 16, LLM & analysis cluster) — a targeted check of whether PDF indexing shares the "project-switch mid-async-operation" bug shape already found three times elsewhere in the same audit (issues #33, #34, #35).

Current behavior (verified against code)

  • src/main/services/pdf-service.ts, init(projectPath) (lines 76-105): the very first thing it does, before any other setup, is if (this.vectorStore) { this.vectorStore.close(); } — unconditionally, with no check for an indexing job still in flight against that store.
  • PdfIndexer receives its vectorStore reference at construction time (constructor-injected, private readonly), so the indexer itself keeps a valid reference and does not silently redirect its writes to the new project — this is not a cross-project data-corruption bug like Zotero sync can write collections into the wrong project if you switch projects mid-sync #33.
  • Instead, because the isolated-child-process PDF extraction step (documented in pass 14) can take up to 120 seconds per PDF with a global sequential queue, there is a real window where a user can switch projects while extraction/indexing for the previous project is still pending. When that indexing job later tries to write (chunk/embedding storage, setDocumentCollections, etc.) to the now-closed better-sqlite3 handle, it throws.

Impact

Switching projects during a long PDF import/index operation can cause that operation to fail with an error, rather than either completing safely or being cleanly cancelled. Given PDF indexing is the app's most central corpus-building operation, and the 120-second extraction window makes the race genuinely reachable in normal use (e.g. importing a large PDF, then immediately switching to another project while it processes), this is a real reliability gap.

Suggested fix

Before closing the previous vectorStore in init(), either wait for any in-flight indexing job on it to complete/abort cleanly, or have the indexer detect a closed store and fail gracefully (e.g. catch and report "indexing cancelled — project changed" rather than an unhandled database error).

Evidence trail

  • src/main/services/pdf-service.ts:76-105init(), unconditional vectorStore.close() with no in-flight-job check.
  • Pass 14's documentation of the isolated child-process PDF extraction architecture (120s timeout, global sequential queue) — the mechanism that makes this race practically reachable.
  • Wiki page corrected in the same pass: 2.-Technical-Architecture.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions