abhigyanpatwari/GitNexus · error · Error
Bridge query prepare failed
Error message
Bridge query prepare failed: ${errMsg} What it means
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.
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).
Example fix
// before
await queryBridge(handle, 'MATCH (a:Repo)-[r:CALLS]->(b:Repo) RETURN a,b', { limit: 10 });
// -> Error: Bridge query prepare failed: Table CALLS does not exist.
// after
await ensureBridgeSchema(handle);
await queryBridge(handle, 'MATCH (a:File)-[r:LINKS_TO]->(b:File) RETURN a,b LIMIT $limit', { limit: 10 }); Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the schema exists and validate Cypher against known labels before querying.
import { ensureBridgeSchema } from './core/group/bridge-db.js';
await ensureBridgeSchema(handle); // idempotent; tolerates already-existing tables
// Build queries only from labels you know the bridge schema defines.
const KNOWN_LABELS = new Set(['Repo', 'File', 'Symbol', 'Contract']);
const labelsIn = (cypher: string): string[] =>
[...cypher.matchAll(/\(([\w]+)?:(\w+)/g)].map((m) => m[2]);
const unknown = labelsIn(cypher).filter((l) => !KNOWN_LABELS.has(l));
if (unknown.length) throw new Error(`query references unknown labels: ${unknown.join(', ')}`); Type guard
export const isBridgePrepareError = (e: unknown): e is Error =>
e instanceof Error && e.message.startsWith('Bridge query prepare failed'); Try / catch
try {
rows = await queryBridge(handle, cypher, params);
} catch (err) {
if (isBridgePrepareError(err)) {
// Parse-level rejection: the driver message names the exact problem.
// Do not retry — fix the Cypher or the schema, then re-run.
throw new Error(`bridge query rejected: ${err.message} (schema drift? re-sync the group)`, {
cause: err,
});
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Prepare failed
- [embed] could not count persisted embeddings; leaving…
- [embed] Failed to delete stale embedding rows — aborting to…
- GitNexus query failed (degraded)
- LadybugDB not initialized. Call initLbug first.
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-08-20).
Data as JSON: /api/errors/5cb7c62f50db4193.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/group/bridge-db.ts:570
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
if (!msg.includes(LBUG_ALREADY_EXISTS_MSG)) throw err;
}
}
}
export async function queryBridge<T>(
handle: BridgeHandle,
cypher: string,
params?: Record<string, LbugValue>,
): Promise<T[]> {
const run = async (): Promise<T[]> => {
const conn = handle._conn as lbug.Connection;
if (params && Object.keys(params).length > 0) {
const stmt = await conn.prepare(cypher);
if (!stmt.isSuccess()) {
const errMsg = await stmt.getErrorMessage();
throw new Error(`Bridge query prepare failed: ${errMsg}`);
}
const queryResult = await conn.execute(stmt, params);
const result = unwrapQueryResult(queryResult);
return (await result.getAll()) as T[];
}
const queryResult = await conn.query(cypher);
const result = unwrapQueryResult(queryResult);
return (await result.getAll()) as T[];
};
// Cached RO handles are shared across concurrent @group callers, so serialize
// conn ops per handle (a LadybugDB Connection is not safe for concurrent
// queries — conn-lock.ts). Uncached/writable handles (the writeBridge temp DB)
// are single-threaded — they're absent from bridgeEntryByHandle and skip the
// lock at zero cost.
const entry = bridgeEntryByHandle.get(handle);
return entry ? withHandleLock(entry, run) : run();
}
View on GitHub (pinned to ac9a4e9abd)