{"record":{"id":"e1bc9d57de3d3042","repo":"tursodatabase/turso","slug":"unsupported-parameter-type-typeof-value","errorCode":null,"errorMessage":"Unsupported parameter type: ${typeof value}","messagePattern":"Unsupported parameter type: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"bindings/react-native/src/Statement.ts","lineNumber":118,"sourceCode":"   * @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)) {\n        this._statement.bindPositionalInt(position, value);\n      } else {\n        this._statement.bindPositionalDouble(position, value);\n      }\n    } else if (typeof value === 'string') {\n      this._statement.bindPositionalText(position, value);\n    } else if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {\n      const buffer = value as unknown as ArrayBuffer;\n      this._statement.bindPositionalBlob(position, buffer);\n    } else {\n      throw new Error(`Unsupported parameter type: ${typeof value}`);\n    }\n  }\n\n  /**\n   * Execute statement without returning rows (for INSERT, UPDATE, DELETE)\n   *\n   * @param params - Optional parameters to bind\n   * @returns Result with changes and lastInsertRowid\n   */\n  async run(...params: BindParams[]): Promise<RunResult> {\n    if (this._finalized) {\n      throw new Error('Statement has been finalized');\n    }\n\n    if (this._execLock) {\n      await this._execLock.acquire();\n    }\n    try {","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/react-native/src/Statement.ts#L100-L136","documentation":"bindValue() accepts numbers (int via bindPositionalInt, floats via bindPositionalDouble), strings (bindPositionalText), and blob data (ArrayBuffer or typed-array views via bindPositionalBlob). Anything else — null/undefined, booleans, plain objects, arrays, Dates — falls through to this TypeError describing the offending typeof.","triggerScenarios":"Binding null or undefined (e.g. optional field that is unset), a boolean flag, a Date object, a plain object/array expecting JSON serialization, or a BigInt — all reach the final else branch of bindValue.","commonSituations":"Inserting API payloads where fields can be null; passing `true/false` for a column stored as 0/1; forgetting to call date.toISOString(); assuming JSON columns auto-serialize; BigInt keys from other libraries.","solutions":["Map values before binding: null/undefined -> sql null support via explicit conversion your schema expects (e.g. bind 0/'' or restructure to avoid the slot), booleans -> 0/1, Dates -> ISO strings, objects/arrays -> JSON.stringify","Add a normalize(value) helper at your data layer so every bound value is number|string|ArrayBuffer","Type your params as SQLiteValue (number | string | ArrayBuffer | TypedArray) so invalid types fail at compile time"],"exampleFix":"// before\nawait stmt.run({\n  id: 1,\n  active: true,          // typeof 'boolean'\n  created: new Date(),   // typeof 'object'\n});\n\n// after\nawait stmt.run({\n  id: 1,\n  active: 1,\n  created: new Date().toISOString(),\n});","handlingStrategy":"validation","validationCode":"type SqlValue = number | string | ArrayBuffer;\n\nfunction normalize(v: unknown): SqlValue {\n  if (v == null) return '';            // or model NULL explicitly per your schema\n  if (typeof v === 'boolean') return v ? 1 : 0;\n  if (v instanceof Date) return v.toISOString();\n  if (typeof v === 'object') return JSON.stringify(v);\n  if (typeof v === 'number' || typeof v === 'string') return v;\n  throw new Error(`Cannot bind value of type ${typeof v}`);\n}\n\nconst safeParams = rawParams.map(normalize);\nawait stmt.run(...safeParams);","typeGuard":"function isBindable(v: unknown): v is number | string | ArrayBuffer | ArrayBufferView {\n  return (\n    typeof v === 'number' ||\n    typeof v === 'string' ||\n    v instanceof ArrayBuffer ||\n    ArrayBuffer.isView(v)\n  );\n}","tryCatchPattern":"try {\n  await stmt.run(params);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Unsupported parameter type:')) {\n    throw new TypeError(`Bound value not a SQLite type: got ${e.message.split(': ')[1]}. Convert booleans/Dates/objects first.`);\n  }\n  throw e;\n}","preventionTips":["Normalize at the data-layer boundary: booleans -> 0/1, Dates -> ISO strings, objects -> JSON.stringify, null -> explicit SQL NULL strategy","Type bind params as number | string | ArrayBuffer (or typed-array views) so invalid kinds fail at compile time","Never assume JSON columns auto-serialize — this binding only accepts SQLite scalars and blobs"],"tags":["react-native","statement","bind-parameters","type-error"],"backgroundTag":"unsupported-bind-type","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"}