tursodatabase/turso · error · InvalidOperationException

CommandText must be set before preparing a command.

Error message

CommandText must be set before preparing a command.

What it means

Prepare() rejects a null, empty, or whitespace-only CommandText with InvalidOperationException (TursoCommand.cs:156-157) because there is no SQL to compile into a native statement. The check uses IsNullOrWhiteSpace, so blank strings are treated like missing SQL.

Source

Thrown at bindings/dotnet/src/Turso.Data/TursoCommand.cs:163

    {
        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)
                    throw new ArgumentException("Parameter must be of type TursoParameter");

View on GitHub (pinned to c1e5928725)

Solutions

  1. Set the SQL before Prepare/Execute: cmd.CommandText = sql; or use new TursoCommand(sql, conn).
  2. If SQL is built dynamically, guard the empty case and skip the database round-trip entirely.
  3. Assert !string.IsNullOrWhiteSpace(cmd.CommandText) in debug builds or startup validation to catch config drift early.

Example fix

// before
var cmd = conn.CreateCommand();
cmd.Prepare(); // CommandText never set -> throws

// after
var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM users WHERE id = @id";
cmd.Prepare();
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(cmd.CommandText))
    throw new InvalidOperationException("Set CommandText before preparing the command.");

Prevention

When it happens

Trigger: cmd.Prepare() (or the first local Execute, which invokes Prepare) when CommandText was never set, set to "", or contains only spaces/tabs/newlines.

Common situations: SQL assembled from a template or configuration that resolves to empty in some environment; a conditional branch that was supposed to set CommandText but was skipped; copy-paste where the assignment line was lost.

Related errors


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