tursodatabase/turso · error · InvalidOperationException

No data exists for the row/column.

Error message

No data exists for the row/column.

What it means

InvalidOperationException ('No data exists for the row/column.') thrown inside GetSchemaTable when a result column resolves to a base table column (baseColumnName and tableName are known and the table's column dictionary reports the column) but the looked-up SchemaColumnInfo is null — a defensive guard against metadata-table inconsistency. In practice this path is nearly unreachable: TryGetValue returning true always yields a non-null info record. If you hit it, the statement's schema metadata (PRAGMA table_info-derived) disagreed with the result-set shape, e.g. for views, CTEs, or DDL raced concurrently.

Source

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

        schema.Columns.Add(SchemaTableColumn.IsLong, typeof(bool));
        schema.Columns.Add(SchemaTableColumn.ProviderType, typeof(int));

        var tableName = TryGetSelectSource(out var parsedTableName, out var selections) ? parsedTableName : null;
        var tableColumns = tableName is null ? new Dictionary<string, SchemaColumnInfo>(StringComparer.OrdinalIgnoreCase) : GetTableColumns(tableName);

        for (var i = 0; i < FieldCount; i++)
        {
            var columnName = GetName(i);
            var selection = i < selections.Count ? selections[i] : columnName;
            var baseColumnName = ResolveBaseColumnName(selection, columnName, tableColumns);
            SchemaColumnInfo? columnInfo = null;
            var hasBaseColumn = baseColumnName is not null && tableName is not null && tableColumns.TryGetValue(baseColumnName, out columnInfo);
            var valueType = TursoBindings.GetValue(statement, i).ValueType;
            if (valueType is TursoValueType.Empty or TursoValueType.Null)
                valueType = GetSampleValueType(i);

            var info = hasBaseColumn
                ? columnInfo ?? throw new InvalidOperationException(Properties.Resources.NoData)
                : null;
            var dataTypeName = info is not null
                ? StripTypeLength(info.TypeName)
                : GetDataTypeNameFromValueType(valueType, selection);
            var dataType = info is not null
                ? GetClrTypeFromSqliteType(info.TypeName, valueType)
                : GetClrTypeFromValueType(valueType);
            var isExpression = info is null;
            var row = schema.NewRow();
            row[SchemaTableColumn.ColumnName] = columnName;
            row[SchemaTableColumn.ColumnOrdinal] = i;
            row[SchemaTableColumn.ColumnSize] = -1;
            row[SchemaTableColumn.NumericPrecision] = DBNull.Value;
            row[SchemaTableColumn.NumericScale] = DBNull.Value;
            row[SchemaTableColumn.IsUnique] = info is not null ? info.IsUnique : DBNull.Value;
            row[SchemaTableColumn.IsKey] = info is not null ? info.IsKey : DBNull.Value;
            row["BaseServerName"] = "";
            row["BaseCatalogName"] = info is not null ? "main" : DBNull.Value;

View on GitHub (pinned to 244cde92a7)

Solutions

  1. Prefer reader.GetColumnSchema() (DbColumn list) for per-column metadata — it does not depend on base-table resolution.
  2. Avoid running GetSchemaTable while another connection mutates the schema; snapshot the schema first.
  3. If reproducible on a stable schema, capture the exact SQL and report it as a binding bug.

Example fix

// before
var table = reader.GetSchemaTable(); // throws on metadata disagreement

// after
var columns = reader.GetColumnSchema(); // lighter, no base-table resolution
foreach (var c in columns) Console.WriteLine($"{c.ColumnName} {c.DataTypeName}");
Defensive patterns

Strategy: fallback

Validate before calling

if (reader.FieldCount == 0) throw new InvalidOperationException("Statement has no columns; skip GetSchemaTable.");

Try / catch

try { schema = reader.GetSchemaTable(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("No data"))
{ schema = null; /* fall back to GetColumnSchema() below */ }
var cols = schema?.Rows.Cast<DataRow>() ?? reader.GetColumnSchema().Select(c => new { c.ColumnName, c.DataTypeName }).Cast<dynamic>();

Prevention

When it happens

Trigger: Calling GetSchemaTable() on a reader whose statement introspects a table that was altered/dropped concurrently; exotic projections over views or CTEs where base-column resolution partially succeeds; this is a guard for internal state disagreement, not a user input error.

Common situations: Migration tools that read schema while another connection alters the same table; schema-introspection utilities calling GetSchemaTable on arbitrary user queries; almost never seen in normal CRUD code.

Related errors


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