tursodatabase/turso · error · ArgumentException

Unknown column: {column}

Error message

Unknown column: {column}

What it means

TursoRow resolves column access by name using a case-insensitive linear scan over the columns the server reported for that statement. If no reported column matches the requested name, IndexOf throws ArgumentException with 'Unknown column: <name>'.

Source

Thrown at bindings/dotnet/src/Turso.Serverless.Client/TursoResultSet.cs:64

    public byte[]? GetBytes(int index) => (byte[]?)_values[index];

    public byte[]? GetBytes(string column) => (byte[]?)this[column];

    public IEnumerator<object?> GetEnumerator() => ((IEnumerable<object?>)_values).GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

    private int IndexOf(string column)
    {
        for (var i = 0; i < _columns.Count; i++)
        {
            if (string.Equals(_columns[i], column, StringComparison.OrdinalIgnoreCase))
            {
                return i;
            }
        }

        throw new ArgumentException($"Unknown column: {column}", nameof(column));
    }
}

/// <summary>The fully materialized result of a SQL statement.</summary>
public sealed class TursoResultSet
{
    internal TursoResultSet(IReadOnlyList<string> columns, IReadOnlyList<string> columnTypes, IReadOnlyList<TursoRow> rows, long rowsAffected, long? lastInsertRowid)
    {
        Columns = columns;
        ColumnTypes = columnTypes;
        Rows = rows;
        RowsAffected = rowsAffected;
        LastInsertRowid = lastInsertRowid;
    }

    /// <summary>Result column names, in order.</summary>
    public IReadOnlyList<string> Columns { get; }

View on GitHub (pinned to 244cde92a7)

Solutions

  1. Inspect the actual names via string.Join(",", result.Columns) and use the exact name returned
  2. Alias columns in SQL to the name your code expects: SELECT user_id AS id FROM ...
  3. Confirm you are reading rows from the statement whose columns you checked
  4. Guard accessors with a helper that falls back to TryGetValue-style lookup during development builds

Example fix

// before
var id = row["userid"]; // column is actually user_id

// after
// SELECT user_id AS userid ...  (alias in SQL)
var id = row["userid"];
Defensive patterns

Strategy: validation

Validate before calling

var names = result.Columns; // IReadOnlyList<string>
if (!names.Contains(column, StringComparer.OrdinalIgnoreCase)) throw new InvalidOperationException($"Column '{column}' not in [{string.Join(",", names)}]");

Type guard

bool HasColumn(TursoResultSet rs, string name) => rs.Columns.Any(c => string.Equals(c, name, StringComparison.OrdinalIgnoreCase));

Try / catch

try { var v = row[column]; } catch (ArgumentException ex) when (ex.Message.StartsWith("Unknown column")) { log.Info($"Available: {string.Join(",", result.Columns)}"); throw; }

Prevention

When it happens

Trigger: row["Name"] when the statement selected name (case-insensitive match saves you, but 'Names' or ' name ' does not); row["id"] on SELECT a, b; indexing a row from one result set with the column list of another; renamed schema columns.

Common situations: SELECT * over a JOIN where the expected column does not exist; schema drift between environments (column renamed in staging); copy-pasted accessors from a different query; trailing whitespace in aliased columns.

Related errors


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