{"record":{"id":"def98ee34fc70467","repo":"abhigyanpatwari/GitNexus","slug":"could-not-read-the-ladybugdb-index-catalog-call-s","errorCode":null,"errorMessage":"Could not read the LadybugDB index catalog (CALL SHOW_INDEXES()); extension-gated DML checks must assume an index may be present.","messagePattern":"Could not read the LadybugDB index catalog \\(CALL SHOW_INDEXES\\(\\)\\); extension-gated DML checks must assume an index may be present\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gitnexus/src/core/lbug/lbug-adapter.ts","lineNumber":3517,"sourceCode":" *\n * `undefined` means \"could not prove anything\" and every caller must treat it\n * as fail-closed (assume an index may be present), never as \"no indexes\". All\n * three readers below honour that, `ftsIndexExistsInCatalog` included since\n * #2841 review H3. To hand ONE read to several gates, use\n * {@link readIndexCatalogSnapshot} — passing this `undefined` on cannot be\n * distinguished from passing nothing at all.\n */\nexport const readIndexCatalogRows = async (): Promise<IndexCatalogRow[] | undefined> => {\n  const targetConn = conn;\n  if (!targetConn) {\n    throw new Error('LadybugDB not initialized. Call initLbug first.');\n  }\n  try {\n    return (await withConnLock(async () =>\n      readQueryRows(await targetConn.query('CALL SHOW_INDEXES() RETURN *')),\n    )) as IndexCatalogRow[];\n  } catch (err) {\n    logger.warn(\n      { err },\n      'Could not read the LadybugDB index catalog (CALL SHOW_INDEXES()); ' +\n        'extension-gated DML checks must assume an index may be present.',\n    );\n    return undefined;\n  }\n};\n\n/**\n * The failed half of an {@link IndexCatalogSnapshot}: the caller DID read the\n * catalog and could not prove anything.\n *\n * It exists because `undefined` was overloaded (#2841 review §5.A). The gates\n * below took `indexRows?: IndexCatalogRow[]`, so \"my read failed\" and \"I passed\n * you nothing\" were the SAME value, and each gate's `?? (await\n * readIndexCatalogRows())` silently re-read the catalog — turning the one shared\n * read the call site documents into three round-trips and three identical\n * warnings on the failure path, with the two gates free to decide from DIFFERENT","sourceCodeStart":3499,"sourceCodeEnd":3535,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/core/lbug/lbug-adapter.ts#L3499-L3535","documentation":"readIndexCatalogRows() could not execute `CALL SHOW_INDEXES() RETURN *` (missing extension in the LadybugDB build, connection fault). It returns undefined instead of rows, and the surrounding IndexCatalogSnapshot model distinguishes 'could not prove anything' from 'proved no index': extension-gated DML checks must then assume an index may be present (conservative).","triggerScenarios":"Any code path calling readIndexCatalogRows() — index-aware DELETE optimization decisions — where the SHOW_INDEXES catalog call throws: older LadybugDB without the extension, a broken connection, or a read-only/busy catalog moment. The function requires initLbug first and throws separately if conn is unset.","commonSituations":"LadybugDB version drift after upgrading the package but not the vendored native build; exotic builds where catalog extensions are compiled out; concurrent access corner cases during startup.","solutions":["Update gitnexus (npm install gitnexus@latest) so the vendored LadybugDB supports SHOW_INDEXES.","Handle the undefined return conservatively — do not treat it as 'no indexes' when deciding on extension-gated DML.","Re-run the operation; transient connection faults resolve on retry.","Check the logged err for the exact engine message if it persists."],"exampleFix":"// before: assuming rows means no index\nconst rows = await readIndexCatalogRows();\nif (rows.length === 0) skipIndexAwarePath();\n\n// after: undefined means unknown — stay conservative\nconst rows = await readIndexCatalogRows();\nif (rows === undefined) assumeIndexMayExist();\nelse if (rows.length === 0) skipIndexAwarePath();","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"type Catalog = IndexCatalogRow[] | undefined; // undefined === 'unknown', NOT 'no indexes'\nfunction catalogProves(rows: Catalog): rows is IndexCatalogRow[] {\n  return Array.isArray(rows);\n}","tryCatchPattern":"const rows = await readIndexCatalogRows(); // never throws; returns undefined on failure\nif (!catalogProves(rows)) {\n  takeConservativePath(); // assume an index may be present\n} else {\n  decideFrom(rows);\n}","preventionTips":["Model the snapshot as 'proved / disproved / unknown' — never collapse unknown into empty.","Keep the gitnexus package updated so SHOW_INDEXES support tracks the engine.","Log the returned err context when unknown recurs; it distinguishes extension-missing from connection faults."],"tags":["ladybugdb","index-catalog","show-indexes","conservative-fallback","version-drift"],"backgroundTag":"index-catalog-unavailable","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}