{"record":{"id":"e1382edb17e6e4be","repo":"tursodatabase/turso","slug":"the-data-is-null-at-ordinal-ordinal","errorCode":null,"errorMessage":"The data is NULL at ordinal {ordinal}.","messagePattern":"The data is NULL at ordinal (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data.Sqlite/SqliteDataReader.cs","lineNumber":248,"sourceCode":"        ValidateOrdinal(ordinal);\n        var valueType = TursoBindings.GetValue(statement, ordinal).ValueType;\n        var declaredType = GetDeclaredTypeName(ordinal);\n        if (!string.IsNullOrEmpty(declaredType))\n            return GetClrTypeFromSqliteType(declaredType, valueType);\n\n        return GetClrTypeFromSqliteType(GetDataTypeName(ordinal), valueType);\n    }\n\n    public override T GetFieldValue<T>(int ordinal)\n    {\n        EnsureOpen();\n        var value = GetValue(ordinal);\n        if (value == DBNull.Value)\n        {\n            if (typeof(T) == typeof(DBNull))\n                return (T)value;\n\n            throw new InvalidOperationException(Properties.Resources.CalledOnNullValue(ordinal));\n        }\n\n        if (typeof(T) == typeof(DBNull))\n            throw new InvalidCastException();\n\n        var targetType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);\n\n        if (targetType == typeof(DateOnly))\n            return (T)(object)DateOnly.FromDateTime(GetDateTime(ordinal));\n\n        if (targetType == typeof(TimeOnly))\n            return (T)(object)TimeOnly.FromTimeSpan(GetTimeSpan(ordinal));\n\n        if (targetType == typeof(DateTime))\n            return (T)(object)GetDateTime(ordinal);\n\n        if (targetType == typeof(DateTimeOffset))\n            return (T)(object)GetDateTimeOffset(ordinal);","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/dotnet/src/Turso.Data.Sqlite/SqliteDataReader.cs#L230-L266","documentation":"InvalidOperationException thrown by GetFieldValue<T> when the requested column holds NULL: the reader returns DBNull.Value and, unless T is exactly DBNull, the call fails with 'The data is NULL at ordinal {ordinal}'. This is the strongly-typed accessor equivalent of SQL null leakage into non-nullable CLR types. Note that Nullable<T> does not help — GetFieldValue<int?> on a NULL column still throws because the DBNull check happens before the target-type switch.","triggerScenarios":"SELECT NULL AS x then reader.GetFieldValue<int>(0); a nullable table column (e.g. deleted_at) that is NULL for the current row, read with GetFieldValue<DateTime>; computed columns like COUNT(*)/MAX(...) returning NULL on empty input.","commonSituations":"Optional fields becoming NULL after a schema migration adds a column; aggregate/LEFT JOIN queries producing NULLs the app did not anticipate; switching from GetString to GetFieldValue<T> assuming nullable semantics.","solutions":["Guard with reader.IsDBNull(ordinal) before the call and supply a default: var v = reader.IsDBNull(i) ? 0 : reader.GetFieldValue<int>(i).","Handle NULL in SQL with COALESCE/IFNULL so the column never reaches the reader as NULL.","If the null case is meaningful, fetch it explicitly: var v = reader.IsDBNull(i) ? (int?)null : reader.GetFieldValue<int>(i)."],"exampleFix":"// before\nvar name = reader.GetFieldValue<string>(ordinal); // throws when NULL\n\n// after\nvar name = reader.IsDBNull(ordinal) ? null : reader.GetFieldValue<string>(ordinal);","handlingStrategy":"validation","validationCode":"var value = reader.IsDBNull(ordinal) ? defaultIfNull : reader.GetFieldValue<int>(ordinal);","typeGuard":"static T? GetOrNull<T>(SqliteDataReader r, int i) where T : struct\n    => r.IsDBNull(i) ? null : r.GetFieldValue<T>(i);","tryCatchPattern":"try { v = reader.GetFieldValue<string>(i); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"NULL\"))\n{ v = fallback; }","preventionTips":["Know which columns are nullable in your schema and guard each with IsDBNull.","Prefer COALESCE in SQL when a sensible default exists.","Remember GetFieldValue<int?> does NOT bypass the NULL check."],"tags":["csharp","dotnet","sqlite","null","data-reader"],"backgroundTag":"sql-null-value-access","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}