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

  1. Read the appended driver message — it names the exact syntax/table the parser choked on; fix the Cypher accordingly.
  2. Ensure ensureBridgeSchema(handle) ran successfully on this handle before querying, and that the group was synced with the current gitnexus version.
  3. 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.
  4. 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

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


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)