tursodatabase/turso · error · ArgumentOutOfRangeException

Column {name} was not found.

Error message

Column {name} was not found.

What it means

ArgumentOutOfRangeException thrown by GetOrdinal when no column matches the requested name either case-sensitively or case-insensitively. The reader exposes only the columns of the current result set, so the name must appear in the executed query's projection — table columns that were not selected are not addressable. Note GetOrdinal does not throw for duplicate names (first match wins); it throws only for no match at all.

Source

Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteDataReader.cs:390

        string? match = null;
        var matchOrdinal = -1;
        for (var i = 0; i < FieldCount; i++)
        {
            if (string.Equals(GetName(i), name, StringComparison.OrdinalIgnoreCase))
            {
                if (match is not null)
                    throw new InvalidOperationException(Properties.Resources.AmbiguousColumnName(name, match, GetName(i)));

                match = GetName(i);
                matchOrdinal = i;
            }
        }

        if (match is not null)
            return matchOrdinal;

        throw new ArgumentOutOfRangeException(nameof(name), name, $"Column {name} was not found.");
    }

    public override DataTable GetSchemaTable()
    {
        EnsureOpen();
        var statement = GetStatement();
        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));
        schema.Columns.Add(SchemaTableColumn.BaseSchemaName, typeof(string));

View on GitHub (pinned to 244cde92a7)

Solutions

  1. Run the query and inspect reader.GetName(0..FieldCount-1) (or EXPLAIN the projection) to see the actual column names, including aliases.
  2. Select columns explicitly (no SELECT *) and alias them to the exact names the code reads.
  3. Resolve ordinals once per query into variables, and add a startup smoke test that runs the query against a test database so renames fail in CI, not production.

Example fix

// before
var i = reader.GetOrdinal("CustomerName"); // column is aliased AS name

// after
var i = reader.GetOrdinal("name"); // match the alias/name in the SELECT list
Defensive patterns

Strategy: validation

Validate before calling

bool HasColumn(SqliteDataReader r, string name)
    => Enumerable.Range(0, r.FieldCount).Any(i => r.GetName(i) == name);

Try / catch

try { var i = reader.GetOrdinal(name); }
catch (ArgumentOutOfRangeException) { /* column really absent: log schema drift, fail that field */ }

Prevention

When it happens

Trigger: GetOrdinal("Name") when the query selected only Id; typos and casing mistakes like GetOrdinal("EMail") for a column named Email; queries changed (column renamed/aliased) while the reading code kept the old name; calling GetOrdinal for a column of a different result set after NextResult().

Common situations: Schema evolution renaming columns without updating reader code; SELECT * combined with column reordering plus name typos; stored query text drifting from the C# mapping after merges.

Related errors


AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20). Data as JSON: /api/errors/9660b120bab78af5. Report an issue: GitHub.