tursodatabase/turso · error · InvalidOperationException
Connection must be set before preparing a command.
Error message
Connection must be set before preparing a command.
What it means
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.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoCommand.cs:161
public override async Task<object?> ExecuteScalarAsync(CancellationToken cancellationToken)
{
await using var reader = await ExecuteDbDataReaderAsync(CommandBehavior.Default, cancellationToken).ConfigureAwait(false);
return await reader.ReadAsync(cancellationToken).ConfigureAwait(false)
? reader.GetValue(0)
: null;
}
public override void Prepare()
{
using var syncOperation = _connection?.EnterSyncOperation();
PrepareCore();
}
private void PrepareCore()
{
if (_connection is null)
throw new InvalidOperationException("Connection must be set before preparing a command.");
if (string.IsNullOrWhiteSpace(CommandText))
throw new InvalidOperationException("CommandText must be set before preparing a command.");
ValidateTransaction();
if (_connection.IsRemote)
return;
TursoStatementHandle? preparedStatement = null;
try
{
var sql = RewriteFacadePragmas(CommandText, _connection);
preparedStatement = TursoBindings.PrepareStatement(_connection.Turso, sql);
var parameterCount = TursoBindings.GetParameterCount(preparedStatement);
var boundParameters = new bool[parameterCount + 1];
for (var i = 0; i < _parameterCollection.Count; i++)
{
var parameter = _parameterCollection[i] as TursoParameter;
if (parameter == null)View on GitHub (pinned to c1e5928725)
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.
Example fix
// before
var cmd = new TursoCommand { CommandText = "SELECT 1" };
cmd.Prepare(); // throws InvalidOperationException
// after
using var conn = new TursoConnection(cs);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT 1";
cmd.Prepare(); Defensive patterns
Strategy: validation
Validate before calling
if (cmd.Connection is not TursoConnection conn || conn.State != ConnectionState.Open)
throw new InvalidOperationException("Open a TursoConnection and bind it to the command first."); Prevention
- 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.
When it happens
Trigger: new TursoCommand { CommandText = "SELECT 1" }.Prepare(); or cmd.ExecuteReader() on a command whose Connection was never assigned or was set back to null.
Common situations: 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.
Related errors
- Connection must be a TursoConnection.
- CommandText must be set before preparing a command.
- Connection must be set before executing a command.
- Command was not prepared.
- The connection is already open.
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-31).
Data as JSON: /api/errors/360a18ad0ef14cbd.
Report an issue: GitHub.