{"record":{"id":"284d48ea6918c3d1","repo":"abhigyanpatwari/GitNexus","slug":"search-index-build-failed-with-an-integrity-error","errorCode":null,"errorMessage":"Search index build failed with an integrity error and the analysis was aborted to avoid publishing a broken index: ${ftsResult.error}. The previous index is left intact. Re-run `gitnexus analyze`; if it persists, check the disk for space or corruption.","messagePattern":"Search index build failed with an integrity error and the analysis was aborted to avoid publishing a broken index: (.+?)\\. The previous index is left intact\\. Re-run `gitnexus analyze`; if it persists, check the disk for space or corruption\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/run-analyze.ts","lineNumber":2754,"sourceCode":"        onIndexStart: options.verbose\n          ? (table, indexName) => log(`FTS: creating ${table}.${indexName}`)\n          : undefined,\n        onIndexReady: options.verbose\n          ? (table, indexName) => log(`FTS: ready ${table}.${indexName}`)\n          : undefined,\n      });\n      if (ftsResult.ok) {\n        progress('fts', 90, 'Search indexes ready');\n      } else if (ftsFailureIsFatal(ftsResult.failureClass, useAtomicSwap)) {\n        // #2658: an IO/rename/checkpoint/corruption failure while building FTS\n        // is a genuinely broken build on this disk — not a concurrent writer\n        // (the single-writer lock rules that out). ONLY fatal on the atomic-swap\n        // path: the graph was built into a throwaway staging DB, so throwing\n        // before the swap abandons the staging file and leaves the previous live\n        // index intact. On an in-place build the live DB is already mutated and\n        // cannot be rolled back by throwing (see ftsFailureIsFatal) — those\n        // degrade in the branch below instead.\n        throw new Error(\n          `Search index build failed with an integrity error and the analysis was aborted ` +\n            `to avoid publishing a broken index: ${ftsResult.error}. The previous index is ` +\n            `left intact. Re-run \\`gitnexus analyze\\`; if it persists, check the disk for space ` +\n            `or corruption.`,\n        );\n      } else {\n        ftsReady = false;\n        ftsSkipReason = 'build-failed';\n        log(\n          `FTS index build failed (${ftsResult.error}) — keyword search degraded this run. ` +\n            'Graph and embeddings analysis completed successfully. Run `gitnexus analyze --repair-fts` to retry.',\n        );\n        progress('fts', 90, 'Search indexes skipped (build failed)');\n      }\n    } else {\n      // For a missing runtime dependency (#2374) the file is present, so the\n      // generic \"install it with network access\" tail in FTS_UNAVAILABLE_MESSAGE\n      // contradicts the remedy's own \"reinstalling will NOT help\" (#2383 F2). Lead","sourceCodeStart":2736,"sourceCodeEnd":2772,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/run-analyze.ts#L2736-L2772","documentation":"Thrown when `buildSearchIndexesOrDegrade` reports a failure classified as fatal by `ftsFailureIsFatal(ftsResult.failureClass, useAtomicSwap)`. This only fires on the atomic-swap build path: the graph was built into a throwaway staging DB, so throwing before the swap abandons the staging file and leaves the previous live index intact. The failure classes that trigger this are IO, rename, checkpoint, or corruption errors — genuinely broken builds on this disk, not transient concurrent-writer issues (the single-writer lock rules those out).","triggerScenarios":"`ftsResult.ok` is false, `ftsFailureIsFatal` returns true because `useAtomicSwap` is true and the failure class is IO/rename/checkpoint/corruption. The analysis aborts before the atomic swap publishes the broken staging index.","commonSituations":"Disk full during FTS index creation; a filesystem rename failure on the atomic swap (cross-device link, permission denied); checkpoint corruption in the staging DB; a failing disk sector during large index writes.","solutions":["Re-run `gitnexus analyze` — the previous live index is intact, so this is safe.","Check disk space (`df -h`) — FTS index creation needs temporary space proportional to indexed content.","If the error persists, run a filesystem check (`fsck` / `chkdsk`) for disk corruption.","If on a cross-device tmp/live setup, ensure the staging and live paths are on the same filesystem (atomic swap uses rename, which fails across mount points)."],"exampleFix":"// before\ngitnexus analyze\n// error: Search index build failed with an integrity error...The previous index is left intact.\n// after\ndf -h                           # check disk space\ngitnexus analyze                # safe to re-run; previous index intact","handlingStrategy":"try-catch","validationCode":"// Before analyze, check available disk space (FTS build needs temp space):\nimport { statfs } from 'fs/promises';\nconst stats = await statfs(repoPath);\nconst freeBytes = stats.bavail * stats.bsize;\nif (freeBytes < 1024 * 1024 * 1024) { // < 1GB\n  console.warn('Low disk space may cause FTS build integrity failures.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runAnalyze(options);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('Search index build failed with an integrity error')) {\n    console.error('Check disk space and filesystem health, then re-run `gitnexus analyze`.');\n    console.error('The previous index is intact — re-running is safe.');\n  }\n  throw err;\n}","preventionTips":["Ensure adequate free disk space before running `gitnexus analyze` — FTS indexing is space-proportional.","Keep the staging and live DB paths on the same filesystem (the atomic swap uses rename, which fails across mount points).","Run filesystem checks periodically on repositories with large indexes."],"tags":["fts","analyze","integrity","disk-space","atomic-swap"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}