{"record":{"id":"da56b714c1d7decb","repo":"tursodatabase/turso","slug":"the-data-reader-has-no-result-sets","errorCode":null,"errorMessage":"The data reader has no result sets.","messagePattern":"The data reader has no result sets\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoRemoteDataReader.cs","lineNumber":297,"sourceCode":"    {\n        return cancellationToken.IsCancellationRequested\n            ? Task.FromCanceled<bool>(cancellationToken)\n            : Task.FromResult(Read());\n    }\n\n    public override int Depth => 0;\n\n    public override IEnumerator GetEnumerator()\n    {\n        return new DbEnumerator(this, closeReader: false);\n    }\n\n    private RemoteStatementResult CurrentResult\n    {\n        get\n        {\n            if (_results.Count == 0)\n                throw new InvalidOperationException(\"The data reader has no result sets.\");\n\n            return _results[_resultIndex];\n        }\n    }\n\n    private bool HasCurrentRow => _rowIndex >= 0 && _rowIndex < CurrentResult.Rows.Count;\n\n    private RemoteResponseValue CurrentValue(int ordinal)\n    {\n        EnsureOpen();\n        if (!HasCurrentRow)\n            throw new InvalidOperationException(\"No current row. Call Read before accessing values.\");\n\n        ValidateOrdinal(ordinal);\n        var row = CurrentResult.Rows[_rowIndex];\n        if (ordinal >= row.Count)\n            throw new IndexOutOfRangeException($\"column ordinal {ordinal} is out of range\");\n","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/dotnet/src/Turso.Data/TursoRemoteDataReader.cs#L279-L315","documentation":"The remote reader keeps a list of RemoteStatementResult sets; the CurrentResult property throws InvalidOperationException when that list is empty. Nearly every member (FieldCount, HasRows, Read, GetName, GetValue) flows through CurrentResult, so a reader constructed with zero result payloads is unusable rather than empty.","triggerScenarios":"Calling ExecuteReader-style APIs on a statement that produces no result payload (INSERT, UPDATE, DELETE, CREATE TABLE, PRAGMA without rows) and then touching any reader property; a code path that constructs TursoRemoteDataReader with an empty results list; an empty or comment-only batch.","commonSituations":"Generic helper methods that always use ExecuteReader regardless of statement kind; batches mixing DDL and SELECT where the first result has no columns; porting code from SqliteClient where a reader for a non-query is merely empty.","solutions":["Use ExecuteNonQuery for INSERT/UPDATE/DELETE/DDL instead of a reader.","If you must branch, decide based on the statement kind or the command API you called, not on reader.FieldCount (which itself throws here).","When running batches, iterate with NextResult() and treat each set according to whether it has columns.","Avoid manually constructing RemoteStatementResult lists with zero entries in tests and harnesses."],"exampleFix":"// before\nusing var reader = command.ExecuteReader(); // INSERT statement, no result set\nConsole.WriteLine(reader.FieldCount); // throws: no result sets\n\n// after\nint affected = command.ExecuteNonQuery();\nConsole.WriteLine(affected);","handlingStrategy":"validation","validationCode":"// choose the API by statement kind before executing\nbool isQuery = sql.TrimStart().StartsWith(\"SELECT\", StringComparison.OrdinalIgnoreCase);\nif (isQuery) { using var r = command.ExecuteReader(); /* ... */ }\nelse { var n = command.ExecuteNonQuery(); }","typeGuard":null,"tryCatchPattern":"try { var fc = reader.FieldCount; }\ncatch (InvalidOperationException) { /* statement produced no result set; nothing to read */ }","preventionTips":["Use ExecuteNonQuery for DML/DDL and readers only for queries.","Keep batches to one statement kind, or walk result sets with NextResult().","Never build readers with empty result lists in tests or custom transports."],"tags":["dotnet","ado-net","result-set","executenonquery"],"backgroundTag":"empty-result-set","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}