abhigyanpatwari/GitNexus · error · Error

Prepare failed: ${errMsg}

Error message

Prepare failed: ${errMsg}

What it means

Thrown by executeParameterized when conn.prepare(cypher) completes but stmt.isSuccess() returns false, meaning the Cypher query failed to compile into a prepared statement. The error message from the statement (retrieved via stmt.getErrorMessage()) is appended. This is a query-syntax or schema-level error: the Cypher parser rejected the query, a referenced label/property doesn't exist, or the parameter placeholders don't match. Distinct from execute-time errors (which throw during conn.execute).

Source

Thrown at gitnexus/src/core/lbug/pool-adapter.ts:1046

    poolSidecarLogger.warn(message),
  );

  const entry = pool.get(repoId);
  if (!entry) {
    throw new Error(`LadybugDB not initialized for repo "${repoId}". Call initLbug first.`);
  }

  entry.lastUsed = Date.now();

  const conn = await checkout(entry);
  silenceStdout();
  activeQueryCount++;
  let queryResult: lbug.QueryResult | lbug.QueryResult[] | undefined;
  try {
    const stmt = await withTimeout(conn.prepare(cypher), QUERY_TIMEOUT_MS, 'Prepare');
    if (!stmt.isSuccess()) {
      const errMsg = await stmt.getErrorMessage();
      throw new Error(`Prepare failed: ${errMsg}`);
    }
    queryResult = await withTimeout(conn.execute(stmt, params), QUERY_TIMEOUT_MS, 'Execute');
    const result = Array.isArray(queryResult) ? queryResult[0] : queryResult;
    const rows = await result.getAll();
    return rows;
  } catch (err) {
    if (isReadOnlyDbError(err)) {
      // Preserve the native error as `cause` so the original frame/message is
      // not lost behind the friendly read-only message (#2068 follow-up).
      throw new Error('Write operations are not allowed. The pool adapter is read-only.', {
        cause: err,
      });
    }
    throw err;
  } finally {
    // Close the native QueryResult cursor(s) before returning the connection —
    // getAll() drains rows but does not release the native cursor, so without
    // this the cursor leaks for the connection's lifetime (#2068 follow-up).

View on GitHub (pinned to d540b00184)

Solutions

  1. Read the appended errMsg from the error — LadybugDB's prepare error pinpoints the syntax issue
  2. Test the Cypher query directly against LadybugDB to isolate the syntax problem
  3. Check that all referenced labels (e.g. :CodeElement, :File) and relationship types exist in the schema defined in schema.ts
  4. Verify parameter placeholder names in the Cypher ($name) match the keys in the params object
  5. If the query uses LadybugDB-specific functions, verify they're supported in the installed version (0.18.0)

Example fix

// before — typo in label name or syntax error
const cypher = 'MATCH (n:CodeElemnt) RETURN n';
// after — correct label name
const cypher = 'MATCH (n:CodeElement) RETURN n';
Defensive patterns

Strategy: validation

Validate before calling

// Validate Cypher syntax before preparing (basic check)
function isValidCypher(cypher: string): boolean {
  const trimmed = cypher.trim().toUpperCase();
  // Must start with a recognized clause
  return /^(MATCH|MERGE|CREATE|RETURN|WITH|CALL|UNWIND|OPTIONAL\s+MATCH)\b/.test(trimmed);
}
// For parameterized queries, verify placeholder names
function validatePlaceholders(cypher: string, params: Record<string, unknown>): void {
  const placeholders = [...cypher.matchAll(/\$(\w+)/g)].map((m) => m[1]);
  const paramKeys = Object.keys(params);
  for (const ph of placeholders) {
    if (!paramKeys.includes(ph)) {
      throw new Error(`Cypher placeholder $${ph} has no matching parameter`);
    }
  }
}

Try / catch

try {
  const rows = await executeParameterized(repoId, cypher, params);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Prepare failed')) {
    // Cypher syntax or schema error — extract the LadybugDB message
    const lbugMsg = e.message.replace('Prepare failed: ', '');
    logger.error(`Cypher prepare error: ${lbugMsg}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling executeParameterized with a Cypher query containing a syntax error, referencing a node label or relationship type that doesn't exist in the schema, using a function not supported by LadybugDB's Cypher dialect, or having mismatched $parameter placeholders. Also triggered by prepare timeout (QUERY_TIMEOUT_MS) via withTimeout wrapping.

Common situations: A GitNexus code change that introduces a Cypher query with a typo or unsupported syntax; a schema change that renamed a label/property but a query still references the old name; a LadybugDB version upgrade that changed Cypher syntax support; dynamically-constructed Cypher that has unescaped special characters or malformed WHERE clauses.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/3ddb0a1281aa11b9. Report an issue: GitHub.