Skip to content

fix(mcp): clear the indexing pin when the 0/0 guard rejects a result - #427

Open
EricSeastrand wants to merge 1 commit into
zilliztech:masterfrom
EricSeastrand:upstream-pr/snapshot-indexing-pin
Open

fix(mcp): clear the indexing pin when the 0/0 guard rejects a result#427
EricSeastrand wants to merge 1 commit into
zilliztech:masterfrom
EricSeastrand:upstream-pr/snapshot-indexing-pin

Conversation

@EricSeastrand

Copy link
Copy Markdown

Problem

SnapshotManager.setCodebaseIndexed() refuses to persist 0 files / 0 chunks / completed — the Issue #295 force-reindex-loop guard, which I added in #296. The guard is correct, but it returns early, and the this.indexingCodebases.delete(codebasePath) that ends the indexing state lives below it:

https://github.com/zilliztech/claude-context/blob/6fc318b/packages/mcp/src/snapshot.ts#L428-L440

So a rejected result leaves the codebase pinned in indexingCodebases with no way out.

Symptoms

  • get_indexing_status reports "currently being indexed, Progress: 100.0%" forever, while nothing is running — the index job finished in milliseconds.
  • After an MCP server restart the same entry resurfaces as "interrupted (MCP server restarted)".
  • index_codebase with force: true changes nothing, because the codebase never leaves the indexing set.

How it is reached

Any scan that legitimately yields zero files after filtering. In my case a repo whose .dockerignore is a single * line — loadIgnorePatterns() globs every .*ignore file in the repo root, so the entire corpus was filtered out and the indexer completed with 0/0. (That ignore-file question is a separate PR; this one is only about the terminal state.) Any over-broad ignore pattern, or an empty/binary-only directory, gets there the same way.

Fix

Replace the bare return with setCodebaseIndexFailed(...) and an actionable message. That helper already clears the indexing entry, so the codebase lands in an honest terminal state (indexfailed, with a reason) instead of a frozen 100%. The #295 protection is unchanged — 0/0/completed is still never persisted as indexed.

Test

packages/mcp/src/snapshot.zero-guard.test.ts:

  • fails on master — after setCodebaseIndexing(path, 100) + a 0/0/completed result, the path is still in getIndexingCodebases();
  • passes with this change — the path is in neither the indexing nor the indexed list, and getCodebaseStatus() is indexfailed;
  • second case asserts a normal non-zero index is still recorded as indexed (guard not over-firing).

It isolates via HOME/USERPROFILE exactly like the existing snapshot.request-options.test.ts, so no new constructor/test seam was needed.

pnpm --filter @zilliz/claude-context-mcp test → 8/8 passing; tsc --noEmit clean.

`SnapshotManager.setCodebaseIndexed()` refuses to persist
`0 files / 0 chunks / completed` (the Issue zilliztech#295 force-reindex-loop guard,
added in zilliztech#296). The guard returns early — but the `indexingCodebases.delete()`
that ends the indexing state lives *below* the guard, so the codebase is left
pinned in `indexingCodebases` forever.

User-visible effect: `get_indexing_status` reports
"currently being indexed, Progress: 100.0%" indefinitely, and after a restart
the same entry comes back as "interrupted (MCP server restarted)".
`force: true` does not help, because the codebase never leaves the indexing
set. The index job itself has already finished — nothing is running.

This is easy to hit whenever a scan legitimately yields zero files (for
example an over-broad ignore pattern): the guard is doing the right thing by
refusing the write, but it leaves the codebase in a state no user action can
clear.

Fix: instead of a bare `return`, record the codebase as `indexfailed` with an
actionable message. `setCodebaseIndexFailed()` already clears the indexing
entry, so the terminal state is honest ("failed, here's why") rather than a
frozen 100%.

Adds `packages/mcp/src/snapshot.zero-guard.test.ts`, which fails on `master`
(the path stays in `getIndexingCodebases()`) and passes with the fix, plus a
companion assertion that a normal non-zero index is still recorded as
`indexed`. It isolates via `HOME`/`USERPROFILE` the same way
`snapshot.request-options.test.ts` does, so no new test seam is needed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant