{"record":{"id":"5cb7c62f50db4193","repo":"abhigyanpatwari/GitNexus","slug":"bridge-query-prepare-failed-errmsg","errorCode":null,"errorMessage":"Bridge query prepare failed: ${errMsg}","messagePattern":"Bridge query prepare failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/group/bridge-db.ts","lineNumber":570,"sourceCode":"    } catch (err: unknown) {\n      const msg = err instanceof Error ? err.message : String(err);\n      if (!msg.includes(LBUG_ALREADY_EXISTS_MSG)) throw err;\n    }\n  }\n}\n\nexport async function queryBridge<T>(\n  handle: BridgeHandle,\n  cypher: string,\n  params?: Record<string, LbugValue>,\n): Promise<T[]> {\n  const run = async (): Promise<T[]> => {\n    const conn = handle._conn as lbug.Connection;\n    if (params && Object.keys(params).length > 0) {\n      const stmt = await conn.prepare(cypher);\n      if (!stmt.isSuccess()) {\n        const errMsg = await stmt.getErrorMessage();\n        throw new Error(`Bridge query prepare failed: ${errMsg}`);\n      }\n      const queryResult = await conn.execute(stmt, params);\n      const result = unwrapQueryResult(queryResult);\n      return (await result.getAll()) as T[];\n    }\n    const queryResult = await conn.query(cypher);\n    const result = unwrapQueryResult(queryResult);\n    return (await result.getAll()) as T[];\n  };\n  // Cached RO handles are shared across concurrent @group callers, so serialize\n  // conn ops per handle (a LadybugDB Connection is not safe for concurrent\n  // queries — conn-lock.ts). Uncached/writable handles (the writeBridge temp DB)\n  // are single-threaded — they're absent from bridgeEntryByHandle and skip the\n  // lock at zero cost.\n  const entry = bridgeEntryByHandle.get(handle);\n  return entry ? withHandleLock(entry, run) : run();\n}\n","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/core/group/bridge-db.ts#L552-L588","documentation":"Thrown by queryBridge() when a parameterized Cypher statement fails LadybugDB's prepare step: conn.prepare(cypher) returned a statement whose isSuccess() is false, and the driver's getErrorMessage() text is appended. It means the bridge database rejected the query text itself before parameters were bound — typically Cypher syntax that LadybugDB does not support, or references to node/rel tables that do not exist in this bridge DB.","triggerScenarios":"Calling queryBridge(handle, cypher, params) with a Cypher string containing Kuzu/GQL syntax LadybugDB's parser rejects (e.g. unsupported functions or clauses), a MATCH against a label absent from the bridge schema (schema drift after the group was synced by an older version), or a typo in a table name introduced when editing the query.","commonSituations":"Upgrading gitnexus changes BRIDGE_SCHEMA_QUERIES or query shapes while an old bridge DB file persists; hand-writing a cross-repo @group query against the wrong table name; a LadybugDB version bump changing supported Cypher grammar.","solutions":["Read the appended driver message — it names the exact syntax/table the parser choked on; fix the Cypher accordingly.","Ensure ensureBridgeSchema(handle) ran successfully on this handle before querying, and that the group was synced with the current gitnexus version.","If the bridge DB predates the current schema (old group sync), re-sync or delete the group's bridge database so it is rebuilt with the current tables.","Confirm every label/rel-type in the query matches the bridge schema tables (check the schema creation statements in bridge-db.ts)."],"exampleFix":"// before\nawait queryBridge(handle, 'MATCH (a:Repo)-[r:CALLS]->(b:Repo) RETURN a,b', { limit: 10 });\n// -> Error: Bridge query prepare failed: Table CALLS does not exist.\n\n// after\nawait ensureBridgeSchema(handle);\nawait queryBridge(handle, 'MATCH (a:File)-[r:LINKS_TO]->(b:File) RETURN a,b LIMIT $limit', { limit: 10 });","handlingStrategy":"try-catch","validationCode":"// Ensure the schema exists and validate Cypher against known labels before querying.\nimport { ensureBridgeSchema } from './core/group/bridge-db.js';\n\nawait ensureBridgeSchema(handle); // idempotent; tolerates already-existing tables\n\n// Build queries only from labels you know the bridge schema defines.\nconst KNOWN_LABELS = new Set(['Repo', 'File', 'Symbol', 'Contract']);\nconst labelsIn = (cypher: string): string[] =>\n  [...cypher.matchAll(/\\(([\\w]+)?:(\\w+)/g)].map((m) => m[2]);\nconst unknown = labelsIn(cypher).filter((l) => !KNOWN_LABELS.has(l));\nif (unknown.length) throw new Error(`query references unknown labels: ${unknown.join(', ')}`);","typeGuard":"export const isBridgePrepareError = (e: unknown): e is Error =>\n  e instanceof Error && e.message.startsWith('Bridge query prepare failed');","tryCatchPattern":"try {\n  rows = await queryBridge(handle, cypher, params);\n} catch (err) {\n  if (isBridgePrepareError(err)) {\n    // Parse-level rejection: the driver message names the exact problem.\n    // Do not retry — fix the Cypher or the schema, then re-run.\n    throw new Error(`bridge query rejected: ${err.message} (schema drift? re-sync the group)`, {\n      cause: err,\n    });\n  }\n  throw err;\n}","preventionTips":["Always run ensureBridgeSchema(handle) once per handle before the first queryBridge call.","Centralize bridge Cypher in constants/helpers instead of inline strings so a schema change breaks one place, not many.","After upgrading gitnexus, re-sync the group so the bridge DB schema matches the query shapes shipped in that version.","Smoke-test group queries in CI against a freshly built bridge DB to catch prepare-time regressions early."],"tags":["database","cypher","ladybugdb","group","query"],"backgroundTag":"database-query-syntax-error","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"}