{"record":{"id":"360a18ad0ef14cbd","repo":"tursodatabase/turso","slug":"connection-must-be-set-before-preparing-a-command","errorCode":null,"errorMessage":"Connection must be set before preparing a command.","messagePattern":"Connection must be set before preparing a command\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoCommand.cs","lineNumber":161,"sourceCode":"\n    public override async Task<object?> ExecuteScalarAsync(CancellationToken cancellationToken)\n    {\n        await using var reader = await ExecuteDbDataReaderAsync(CommandBehavior.Default, cancellationToken).ConfigureAwait(false);\n        return await reader.ReadAsync(cancellationToken).ConfigureAwait(false)\n            ? reader.GetValue(0)\n            : null;\n    }\n\n    public override void Prepare()\n    {\n        using var syncOperation = _connection?.EnterSyncOperation();\n        PrepareCore();\n    }\n\n    private void PrepareCore()\n    {\n        if (_connection is null)\n            throw new InvalidOperationException(\"Connection must be set before preparing a command.\");\n        if (string.IsNullOrWhiteSpace(CommandText))\n            throw new InvalidOperationException(\"CommandText must be set before preparing a command.\");\n        ValidateTransaction();\n        if (_connection.IsRemote)\n            return;\n\n        TursoStatementHandle? preparedStatement = null;\n        try\n        {\n            var sql = RewriteFacadePragmas(CommandText, _connection);\n            preparedStatement = TursoBindings.PrepareStatement(_connection.Turso, sql);\n            var parameterCount = TursoBindings.GetParameterCount(preparedStatement);\n            var boundParameters = new bool[parameterCount + 1];\n\n            for (var i = 0; i < _parameterCollection.Count; i++)\n            {\n                var parameter = _parameterCollection[i] as TursoParameter;\n                if (parameter == null)","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/bindings/dotnet/src/Turso.Data/TursoCommand.cs#L143-L179","documentation":"Prepare() compiles CommandText into a native statement through the connection's database handle, so it requires a bound connection (TursoCommand.cs:152-155). Calling Prepare — or any local Execute, which calls Prepare internally — while Connection is null throws InvalidOperationException before any SQL is parsed.","triggerScenarios":"new TursoCommand { CommandText = \"SELECT 1\" }.Prepare(); or cmd.ExecuteReader() on a command whose Connection was never assigned or was set back to null.","commonSituations":"Object-initializer ordering mistakes where Prepare/Execute precedes Connection assignment; unit tests constructing commands standalone; long-lived command objects reused after the connection was unbound; forgetting that Turso (unlike SqlClient pooling) does not auto-open/attach.","solutions":["Assign the connection first: cmd.Connection = conn; then call Prepare().","Prefer creating commands from the connection: using var cmd = conn.CreateCommand(); so the binding always exists.","Null-check cmd.Connection in shared helpers and throw your own descriptive error early."],"exampleFix":"// before\nvar cmd = new TursoCommand { CommandText = \"SELECT 1\" };\ncmd.Prepare(); // throws InvalidOperationException\n\n// after\nusing var conn = new TursoConnection(cs);\nconn.Open();\nvar cmd = conn.CreateCommand();\ncmd.CommandText = \"SELECT 1\";\ncmd.Prepare();","handlingStrategy":"validation","validationCode":"if (cmd.Connection is not TursoConnection conn || conn.State != ConnectionState.Open)\n    throw new InvalidOperationException(\"Open a TursoConnection and bind it to the command first.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create commands via conn.CreateCommand() so a connection is always bound.","Call Open before Prepare on local databases.","Null-check Connection in shared helpers to fail with context-rich errors."],"tags":["dotnet","ado-net","tursodb","connection","prepare"],"backgroundTag":"connection-not-set","analyzedSha":"c1e59287258d99b309e362a63f48822256e2f65f","analyzedAt":"2026-08-31T11:17:35.598Z","contentChangedAt":"2026-08-31T11:17:35.598Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}