tursodatabase/turso · error · Error
Failed to get column name at index ${i}
Error message
Failed to get column name at index ${i} What it means
Statement.readRow() iterates from 0 to columnCount()-1 calling the native columnName(i); a falsy (null or empty) name at any index throws with that index. The count and names come from the native JSI host object, so for a valid prepared SELECT this should be impossible — hitting it means the JSI metadata layer is not returning what the JS side expects.
Source
Thrown at bindings/react-native/src/Statement.ts:340
if (this._execLock) {
this._execLock.release();
}
}
}
/**
* Read current row into an object
*
* @returns Row object with column name keys
*/
private readRow(): Row {
const row: Row = {};
const columnCount = this._statement.columnCount();
for (let i = 0; i < columnCount; i++) {
const name = this._statement.columnName(i);
if (!name) {
throw new Error(`Failed to get column name at index ${i}`);
}
const value = this.readColumnValue(i);
row[name] = value;
}
return row;
}
/**
* Read value at column index
*
* @param index - Column index
* @returns Column value
*/
private readColumnValue(index: number): SQLiteValue {
const kind = this._statement.rowValueKind(index);
View on GitHub (pinned to bad083fafb)
Solutions
- Fully rebuild the native module: cd ios && pod install (or pod deintegrate && pod install) and a clean Android build (./gradlew clean)
- Reset Metro caches: npx react-native start --reset-cache
- Pin the npm package and the native pod/package to matching versions
- Ensure no code path finalizes the statement or closes the database while a get() row read is in flight
Example fix
# before npm install @tursodatabase/sync-react-native@latest # app throws: Failed to get column name at index 3 # after cd ios && pod deintegrate && pod install && cd .. cd android && ./gradlew clean && cd .. npx react-native start --reset-cache
Defensive patterns
Strategy: try-catch
Type guard
function isColumnNameError(e: unknown): boolean {
return e instanceof Error && /Failed to get column name at index \d+/.test(e.message);
} Try / catch
try {
const row = await stmt.get(id);
} catch (e) {
if (isColumnNameError(e)) {
// binding/native skew: rebuild native + reset Metro, then retry once
throw new Error('Native/JS binding mismatch — run pod install / gradlew clean and --reset-cache');
}
throw e;
} Prevention
- Upgrade the npm package and native module together, always followed by pod install / clean gradle build
- Reset Metro cache after SDK upgrades
- Pin matching JS and native versions in lockfiles
- Never close the database while a row read is in flight
When it happens
Trigger: JS package and native binary built from different revisions (columnName returning undefined for an index the JS columnCount trusts); the statement being finalized concurrently between the columnCount() call and the name-read loop; a native build where the host object was not registered correctly.
Common situations: Upgrading @tursodatabase/sync-react-native in package.json without rebuilding pods/gradle artifacts; stale Metro cache serving old JS against a new native module; CI builds with cached native artifacts; Expo prebuild caches.
Related errors
- Unknown column type: ${kind}
- Turso native module not loaded
- @tursodatabase/sync-react-native: Failed to install JSI bind
- @tursodatabase/sync-react-native: JSI bindings not found on
- Unknown result type: ${resultKind}
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/637035d493e16839.
Report an issue: GitHub.