{"record":{"id":"3346a989d5ba48c8","repo":"tursodatabase/turso","slug":"unknown-parameter-name-name","errorCode":null,"errorMessage":"Unknown parameter name: ${name}","messagePattern":"Unknown parameter name: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"bindings/react-native/src/Statement.ts","lineNumber":89,"sourceCode":"    for (let i = 0; i < params.length; i++) {\n      const position = i + 1; // 1-indexed\n      const value = params[i]!;\n\n      this.bindValue(position, value);\n    }\n  }\n\n  /**\n   * Bind named parameters\n   *\n   * @param params - Object with named parameters\n   */\n  private bindNamed(params: Record<string, SQLiteValue>): void {\n    for (const [name, value] of Object.entries(params)) {\n      // Get position for named parameter\n      const position = this._statement.namedPosition(name);\n      if (position < 0) {\n        throw new Error(`Unknown parameter name: ${name}`);\n      }\n\n      this.bindValue(position, value);\n    }\n  }\n\n  /**\n   * Bind a single value at a position\n   *\n   * @param position - 1-indexed position\n   * @param value - Value to bind\n   */\n  private bindValue(position: number, value: SQLiteValue): void {\n    if (value === null || value === undefined) {\n      this._statement.bindPositionalNull(position);\n    } else if (typeof value === 'number') {\n      // Check if integer or float\n      if (Number.isInteger(value)) {","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/react-native/src/Statement.ts#L71-L107","documentation":"bindNamed() looks up each object key via the native namedPosition(name); a return value below 0 means the SQL text contains no parameter with that name. SQLite named parameters are spelled :name, @name, or $name in SQL, and the lookup must agree with the object key, so any mismatch between the SQL placeholder names and the keys of the params object triggers this.","triggerScenarios":"Passing an object to stmt.run/get/all/bind whose keys don't match the SQL: `stmt.get({ id: 1 })` for 'SELECT * FROM users WHERE id = :identifier'; prefix mismatch (SQL uses :name but the key includes or omits the prefix differently than namedPosition expects); passing named params to a statement that uses ? positional placeholders.","commonSituations":"Renaming a SQL placeholder without updating the params object; mixing conventions between code (camelCase keys) and SQL (snake_case names); copy-pasting query text between modules with different placeholder styles; passing an object to a ?-based query where the engine treats it as named params.","solutions":["Make each object key exactly match the placeholder name in the SQL text (same spelling and prefix style, e.g. ':name' in SQL and the matching key form in JS)","If unsure of the accepted form, test both bare and prefixed key spellings against your SQL in isolation","For ?-style SQL, pass an array or positional values instead of an object","Derive params from a single source (typed constant) shared by the SQL string and the bind object so renames stay in sync"],"exampleFix":"// before\nconst stmt = db.prepare('SELECT * FROM users WHERE id = :identifier');\nawait stmt.get({ id: 1 }); // throws \"Unknown parameter name: id\"\n\n// after\nconst stmt = db.prepare('SELECT * FROM users WHERE id = :identifier');\nawait stmt.get({ identifier: 1 });","handlingStrategy":"validation","validationCode":"// Keep SQL placeholders and bind keys in one typed constant so they cannot drift\nconst FIND_USER = {\n  sql: 'SELECT * FROM users WHERE id = :id AND tenant = :tenant',\n  params: (id: number, tenant: string) => ({ id, tenant }), // keys match exactly\n} as const;\n\nawait db.get(FIND_USER.sql, FIND_USER.params(1, 'acme'));","typeGuard":"function hasOnlyStringNumberBufferValues(\n  params: Record<string, unknown>\n): params is Record<string, number | string | ArrayBuffer> {\n  return Object.values(params).every(\n    (v) => typeof v === 'number' || typeof v === 'string' || v instanceof ArrayBuffer\n  );\n}","tryCatchPattern":"try {\n  await stmt.run({ id: 1 });\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Unknown parameter name:')) {\n    const bad = e.message.split(': ')[1];\n    throw new Error(`Placeholder mismatch: key \"${bad}\" is not in the SQL text`);\n  }\n  throw e;\n}","preventionTips":["Derive bind keys and SQL from a single shared constant per query","Settle on one placeholder prefix style (:name) across the codebase","Use arrays/positional params for ?-style SQL, objects only for named placeholders"],"tags":["react-native","statement","bind-parameters","named-parameters"],"backgroundTag":"unknown-bind-parameter","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}