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

  1. Resolve ordinals at runtime with reader.GetOrdinal("columnName") instead of hardcoding indices.
  2. Check ordinal >= 0 && ordinal < reader.FieldCount before access.
  3. 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

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


AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06). Data as JSON: /api/errors/4132a44bd48776ef. Report an issue: GitHub.