tursodatabase/turso · error · IndexOutOfRangeException
column ordinal {ordinal} is out of range
Error message
column ordinal {ordinal} is out of range What it means
ValidateOrdinal guards column-index access on TursoDataReader: negative ordinals or ordinals >= FieldCount throw IndexOutOfRangeException with the message 'column ordinal {ordinal} is out of range'. It backs GetDataTypeName and GetFieldType.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoDataReader.cs:334
};
}
private void EnsureOpen()
{
if (IsClosed)
throw new InvalidOperationException("The data reader is closed.");
}
private void RunExternalIo()
{
_syncConnection?.RunExternalIo();
}
private void ValidateOrdinal(int ordinal)
{
ArgumentOutOfRangeException.ThrowIfNegative(ordinal);
if (ordinal >= FieldCount)
throw new IndexOutOfRangeException($"column ordinal {ordinal} is out of range");
}
}
internal static class DataReaderCompatibility
{
public static DataTable CreateSchemaTable(DbDataReader reader)
{
var schema = new DataTable("SchemaTable");
schema.Columns.Add(SchemaTableColumn.ColumnName, typeof(string));
schema.Columns.Add(SchemaTableColumn.ColumnOrdinal, typeof(int));
schema.Columns.Add(SchemaTableColumn.ColumnSize, typeof(int));
schema.Columns.Add(SchemaTableColumn.NumericPrecision, typeof(short));
schema.Columns.Add(SchemaTableColumn.NumericScale, typeof(short));
schema.Columns.Add(SchemaTableColumn.IsUnique, typeof(bool));
schema.Columns.Add(SchemaTableColumn.IsKey, typeof(bool));
schema.Columns.Add("BaseServerName", typeof(string));
schema.Columns.Add("BaseCatalogName", typeof(string));
schema.Columns.Add(SchemaTableColumn.BaseColumnName, typeof(string));View on GitHub (pinned to 6c72522679)
Solutions
- Resolve ordinals at runtime with reader.GetOrdinal("columnName") instead of hardcoding indices.
- Check ordinal >= 0 && ordinal < reader.FieldCount before access.
- Fix the SELECT statement so it returns the expected number of columns.
Example fix
// before
var type = reader.GetFieldType(5); // query only returns 3 columns
// after
int ord = reader.GetOrdinal("created_at");
var type = reader.GetFieldType(ord); Defensive patterns
Strategy: validation
Validate before calling
if (ordinal >= 0 && ordinal < reader.FieldCount)
return reader.GetFieldType(ordinal); Type guard
static bool IsValidOrdinal(DbDataReader r, int ordinal) => ordinal >= 0 && ordinal < r.FieldCount;
Try / catch
try { return reader.GetFieldType(ordinal); }
catch (IndexOutOfRangeException ex) when (ex.Message.Contains("column ordinal"))
{ throw new DataException($"Ordinal {ordinal} invalid; FieldCount={reader.FieldCount}", ex); } Prevention
- Use GetOrdinal(name) instead of hardcoded indices.
- Recompute ordinals whenever the SELECT list changes.
- Add Debug.Assert(ordinal < reader.FieldCount) in mapping code.
When it happens
Trigger: Calling GetFieldType(ordinal)/GetDataTypeName(ordinal) with an index beyond the result set's column count or a negative value — typically from hardcoded ordinals, stale ordinal caches, or iterating past the schema's column count.
Common situations: Hardcoding column indices after changing the SELECT list; reusing ordinals captured from a previous query's schema; mapping DTOs with more fields than the query selects.
Related errors
- Cannot convert {value.GetType()} value to Guid.
- Embedded replica sync is not supported yet by the .NET provi
- Embedded replica connections are not supported yet by the .N
- Sync Interval requires embedded replica support, which is no
- Auth Token requires a remote Turso URL Data Source.
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06).
Data as JSON: /api/errors/4132a44bd48776ef.
Report an issue: GitHub.