{"record":{"id":"3ddb0a1281aa11b9","repo":"abhigyanpatwari/GitNexus","slug":"prepare-failed-errmsg-3ddb0a","errorCode":null,"errorMessage":"Prepare failed: ${errMsg}","messagePattern":"Prepare failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/lbug/pool-adapter.ts","lineNumber":1046,"sourceCode":"    poolSidecarLogger.warn(message),\n  );\n\n  const entry = pool.get(repoId);\n  if (!entry) {\n    throw new Error(`LadybugDB not initialized for repo \"${repoId}\". Call initLbug first.`);\n  }\n\n  entry.lastUsed = Date.now();\n\n  const conn = await checkout(entry);\n  silenceStdout();\n  activeQueryCount++;\n  let queryResult: lbug.QueryResult | lbug.QueryResult[] | undefined;\n  try {\n    const stmt = await withTimeout(conn.prepare(cypher), QUERY_TIMEOUT_MS, 'Prepare');\n    if (!stmt.isSuccess()) {\n      const errMsg = await stmt.getErrorMessage();\n      throw new Error(`Prepare failed: ${errMsg}`);\n    }\n    queryResult = await withTimeout(conn.execute(stmt, params), QUERY_TIMEOUT_MS, 'Execute');\n    const result = Array.isArray(queryResult) ? queryResult[0] : queryResult;\n    const rows = await result.getAll();\n    return rows;\n  } catch (err) {\n    if (isReadOnlyDbError(err)) {\n      // Preserve the native error as `cause` so the original frame/message is\n      // not lost behind the friendly read-only message (#2068 follow-up).\n      throw new Error('Write operations are not allowed. The pool adapter is read-only.', {\n        cause: err,\n      });\n    }\n    throw err;\n  } finally {\n    // Close the native QueryResult cursor(s) before returning the connection —\n    // getAll() drains rows but does not release the native cursor, so without\n    // this the cursor leaks for the connection's lifetime (#2068 follow-up).","sourceCodeStart":1028,"sourceCodeEnd":1064,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/lbug/pool-adapter.ts#L1028-L1064","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the appended errMsg from the error — LadybugDB's prepare error pinpoints the syntax issue","Test the Cypher query directly against LadybugDB to isolate the syntax problem","Check that all referenced labels (e.g. :CodeElement, :File) and relationship types exist in the schema defined in schema.ts","Verify parameter placeholder names in the Cypher ($name) match the keys in the params object","If the query uses LadybugDB-specific functions, verify they're supported in the installed version (0.18.0)"],"exampleFix":"// before — typo in label name or syntax error\nconst cypher = 'MATCH (n:CodeElemnt) RETURN n';\n// after — correct label name\nconst cypher = 'MATCH (n:CodeElement) RETURN n';","handlingStrategy":"validation","validationCode":"// Validate Cypher syntax before preparing (basic check)\nfunction isValidCypher(cypher: string): boolean {\n  const trimmed = cypher.trim().toUpperCase();\n  // Must start with a recognized clause\n  return /^(MATCH|MERGE|CREATE|RETURN|WITH|CALL|UNWIND|OPTIONAL\\s+MATCH)\\b/.test(trimmed);\n}\n// For parameterized queries, verify placeholder names\nfunction validatePlaceholders(cypher: string, params: Record<string, unknown>): void {\n  const placeholders = [...cypher.matchAll(/\\$(\\w+)/g)].map((m) => m[1]);\n  const paramKeys = Object.keys(params);\n  for (const ph of placeholders) {\n    if (!paramKeys.includes(ph)) {\n      throw new Error(`Cypher placeholder $${ph} has no matching parameter`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const rows = await executeParameterized(repoId, cypher, params);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Prepare failed')) {\n    // Cypher syntax or schema error — extract the LadybugDB message\n    const lbugMsg = e.message.replace('Prepare failed: ', '');\n    logger.error(`Cypher prepare error: ${lbugMsg}`);\n  }\n  throw e;\n}","preventionTips":["Test Cypher queries against LadybugDB directly before integrating them into GitNexus code","Use TypeScript template literal types or constants for label/relationship names to prevent typos","Validate that all $placeholder names in Cypher match params object keys before calling prepare","Keep schema.ts label/property names in sync with query strings — refactor together, not separately"],"tags":["ladybugdb","cypher","prepare-failed","query-syntax","pool-adapter"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}