{"record":{"id":"fbb3cdba3366cad3","repo":"abhigyanpatwari/GitNexus","slug":"failed-to-remove-the-ladybugdb-index-files-still","errorCode":null,"errorMessage":"Failed to remove the LadybugDB index files — still present after 5 attempts:\n${survivors.map((p) => `  - ${p}`).join('\\n')}\nThe blocking handle may be another process, a lingering handle from this process's just-closed database, or an antivirus scan — an immediate re-run often succeeds. If it persists, stop any GitNexus MCP or serve process using this repository, add an antivirus exclusion for the GitNexus storage directory, then re-run the analyze.","messagePattern":"Failed to remove the LadybugDB index files — still present after 5 attempts:\n(.+?)`\\)\\.join\\('\\\\n'\\)\\}\nThe blocking handle may be another process, a lingering handle from this process's just-closed database, or an antivirus scan — an immediate re-run often succeeds\\. If it persists, stop any GitNexus MCP or serve process using this repository, add an antivirus exclusion for the GitNexus storage directory, then re-run the analyze\\.","errorType":"exception","errorClass":"LbugWipeError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/lbug/lbug-adapter.ts","lineNumber":2495,"sourceCode":"      if (!gone) survivors.push(f);\n    }\n    if (survivors.length === 0) return;\n    if (attempt < HANDLE_RELEASE_PROBE_ATTEMPTS) {\n      await sleep(HANDLE_RELEASE_PROBE_DELAY_MS * attempt);\n    }\n  }\n\n  // Class split (FIX 2): the contentless `.lock` never fails the wipe.\n  const dataSurvivors = survivors.filter((f) => f !== lockPath);\n  if (survivors.includes(lockPath)) {\n    logger.warn(\n      `GitNexus: ${lockPath} is still present after the wipe retries — continuing: the ` +\n        'lock file is contentless and initLbug recreates it; a genuinely held lock will ' +\n        \"surface as the reopen's own lock-busy error.\",\n    );\n  }\n  if (dataSurvivors.length > 0) {\n    throw new LbugWipeError(dataSurvivors);\n  }\n};\n\nexport const isLbugReady = (): boolean => conn !== null && db !== null;\n\n/**\n * Multi-label alternation over exactly the labels that can own embedding\n * rows: EMBEDDABLE_LABELS plus File, which embedding-pipeline.ts embeds as\n * the zero-symbol fallback for text-only repositories (#2454). Reserved\n * keywords are backtick-escaped via {@link escapeTableName}. Probed on\n * @ladybugdb/core 0.18.0 (this shipping review, FIX 4): the full multi-label\n * alternation parses, executes, and deletes exactly the joined rows —\n * replacing the unlabeled `MATCH (n)` that scanned EVERY node table per\n * chunk (BasicBlock-dominated under `--pdg`) when only embeddable labels\n * can match an embedding row. Including File is free for code repositories:\n * they never hold File embedding rows, so the extra label joins nothing.\n */\nconst embeddableLabelMatch = (): string =>","sourceCodeStart":2477,"sourceCodeEnd":2513,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/core/lbug/lbug-adapter.ts#L2477-L2513","documentation":"LbugWipeError from wipeLbugDbFiles (gitnexus/src/core/lbug/lbug-adapter.ts:2383). A full-rebuild wipe rm-probes each member of the 4-file family (<db>, .wal, .shadow, .lock) and counts it gone only on ENOENT. After HANDLE_RELEASE_PROBE_ATTEMPTS (5) retries, data-bearing survivors — everything except the contentless .lock, which is tolerated with a warning — fail the rebuild, because reopening would resurrect rows the run believes it wiped.","triggerScenarios":"gitnexus analyze --force (or the #2409 escalation wipe) while another GitNexus MCP/serve process still holds the database files open; Windows delete-pending handle-release lag; an antivirus scan holding handles on the storage directory.","commonSituations":"Forgetting to stop `gitnexus serve` or an MCP session before a forced rebuild on Windows; on-access AV scanners touching the storage dir mid-wipe; a just-closed database in the same process whose handles have not been released yet.","solutions":["Immediately re-run the analyze — transient handle-release lag often clears on its own","Stop every GitNexus MCP or serve process using this repository, then re-run","Add an antivirus exclusion for the GitNexus storage directory","On POSIX, confirm no holder remains: lsof +D <storage-dir>, kill the listed PIDs, re-run"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before a forced rebuild, confirm nothing holds the index family open (POSIX)\nimport { execFile } from 'node:child_process';\nconst holders = await new Promise<string>((res) =>\n  execFile('lsof', ['-t', dbPath, `${dbPath}.wal`, `${dbPath}.shadow`],\n    (_e, stdout) => res(stdout.toString().trim())),\n);\nif (holders) throw new Error(`index still held by PIDs: ${holders}`);","typeGuard":"import { LbugWipeError } from '../core/lbug/lbug-adapter.js';\nconst isLbugWipeError = (e: unknown): e is LbugWipeError => e instanceof LbugWipeError;","tryCatchPattern":"try {\n  await wipeLbugDbFiles(dbPath);\n} catch (e) {\n  if (isLbugWipeError(e)) {\n    // transient handle lag — stop holders, then retry the wipe once before failing\n    await stopGitNexusServeProcesses();\n    await retryOnce(() => wipeLbugDbFiles(dbPath));\n  }\n  throw e;\n}","preventionTips":["Stop `gitnexus serve` and MCP sessions before any forced full rebuild","Add an antivirus exclusion for the GitNexus storage directory on Windows hosts","Treat a wipe failure as retryable-once — handle-release lag usually clears in seconds"],"tags":["gitnexus","ladybugdb","file-lock","windows","antivirus","full-rebuild"],"backgroundTag":"file-in-use-by-another-process","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}