tursodatabase/turso · error · ArgumentException

Batch command must be a TursoBatchCommand.

Error message

Batch command must be a TursoBatchCommand.

What it means

TursoBatchCommandCollection.RequireTursoBatchCommand validates every DbBatchCommand passed to Add, Insert, or the indexer setter (TursoBatchCommandCollection.cs:70-75). ADO.NET batch collections are provider-specific, so a command object created by another provider (SqlBatchCommand, NpgsqlBatchCommand) or a custom DbBatchCommand subclass is rejected with ArgumentException instead of failing later during execution.

Source

Thrown at bindings/dotnet/src/Turso.Data/TursoBatchCommandCollection.cs:78

    protected override DbBatchCommand GetBatchCommand(int index)
    {
        return _commands[index];
    }

    protected override void SetBatchCommand(int index, DbBatchCommand batchCommand)
    {
        _commands[index] = RequireTursoBatchCommand(batchCommand);
    }

    internal IReadOnlyList<TursoBatchCommand> AsReadOnly()
    {
        return _commands;
    }

    private static TursoBatchCommand RequireTursoBatchCommand(DbBatchCommand command)
    {
        return command as TursoBatchCommand
               ?? throw new ArgumentException("Batch command must be a TursoBatchCommand.", nameof(command));
    }
}

View on GitHub (pinned to 244cde92a7)

Solutions

  1. Construct entries directly: batch.Commands.Add(new TursoBatchCommand { CommandText = ... }).
  2. Use TursoFactory (the Turso DbProviderFactory) consistently so connection, batch, and commands all come from the same provider.
  3. Audit generic batch-building helpers and replace mixed-provider objects with ones created by the connection that owns the batch.

Example fix

// before
var batch = conn.CreateBatch();
batch.Commands.Add(new SqlBatchCommand { CommandText = "SELECT 1" }); // throws ArgumentException

// after
var batch = conn.CreateBatch();
batch.Commands.Add(new TursoBatchCommand { CommandText = "SELECT 1" });
Defensive patterns

Strategy: type-guard

Validate before calling

foreach (var c in commandsToAdd)
{
    if (c is not TursoBatchCommand)
        throw new InvalidOperationException($"{c.GetType().Name} cannot be added to a TursoBatch.");
}

Type guard

static bool IsTursoBatchCommand(DbBatchCommand c) => c is TursoBatchCommand;

Try / catch

try
{
    batch.Commands.Add(cmd);
}
catch (ArgumentException ex) when (ex.Message.Contains("TursoBatchCommand"))
{
    // Replace the foreign entry with one created for this batch.
    var tursoCmd = new TursoBatchCommand { CommandText = cmd.CommandText };
    batch.Commands.Add(tursoCmd);
}

Prevention

When it happens

Trigger: batch.Commands.Add(new SqlBatchCommand(...)); or inserting/assigning any DbBatchCommand that is not a TursoBatchCommand instance into a TursoBatch's Commands collection.

Common situations: Provider-agnostic data-access layers written against the abstract DbBatch/DbBatchCommand types; copy-pasted SqlClient batch snippets; resolving the wrong DbProviderFactory from DbProviderFactories so foreign batch commands flow into a TursoBatch.

Related errors


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