tursodatabase/turso · error · ArgumentException
Parameter must be of type TursoParameter
Error message
Parameter must be of type TursoParameter
What it means
Inside Prepare(), every parameter read from the Parameters collection is cast to TursoParameter before its value can be marshalled to the native engine via ToValue() (TursoCommand.cs:170-174). A failed cast throws ArgumentException. Note that the stock TursoParameterCollection wraps foreign objects into TursoParameter on Add/Insert, so in practice this is a defensive invariant most reachable through a derived parameter collection or overridden parameter accessors.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoCommand.cs:180
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");
if (!string.IsNullOrEmpty(parameter.ParameterName))
{
var parameterIndex = TursoBindings.BindNamedParameter(preparedStatement, parameter.ParameterName, parameter.ToValue());
if (parameterIndex == 0)
throw new InvalidOperationException($"Parameter {parameter.ParameterName} was not found in the SQL statement.");
boundParameters[parameterIndex] = true;
}
else
{
var parameterIndex = i + 1;
if (parameterIndex > parameterCount)
throw new InvalidOperationException($"Parameter at position {parameterIndex} was not found in the SQL statement.");
TursoBindings.BindParameter(preparedStatement, parameterIndex, parameter.ToValue());
boundParameters[parameterIndex] = true;
}View on GitHub (pinned to c1e5928725)
Solutions
- Create parameters with cmd.CreateParameter() or cmd.Parameters.AddWithValue(name, value) so every entry is a TursoParameter.
- Do not subclass or swap out the parameter collection that TursoCommand uses.
- If you wrap parameters generically, unwrap to a TursoParameter (or its raw value) before inserting into Parameters.
Example fix
// before
customWrapperCollection.Add(new SqlParameter("@id", 42));
cmd.Prepare(); // indexer returns SqlParameter -> throws ArgumentException
// after
cmd.Parameters.AddWithValue("@id", 42);
cmd.Prepare(); Defensive patterns
Strategy: type-guard
Validate before calling
foreach (DbParameter p in cmd.Parameters)
{
if (p is not TursoParameter)
throw new InvalidOperationException($"{p.GetType().Name} cannot be bound by TursoCommand.");
} Type guard
static bool AllParametersAreTurso(DbParameterCollection ps) => ps.Cast<DbParameter>().All(p => p is TursoParameter);
Try / catch
try
{
cmd.Prepare();
}
catch (ArgumentException ex) when (ex.Message.Contains("TursoParameter"))
{
// Rebuild the collection with cmd.CreateParameter()/AddWithValue and retry.
} Prevention
- Add parameters only via cmd.Parameters.AddWithValue or cmd.CreateParameter().
- Do not subclass or replace the parameter collection used by TursoCommand.
- Unwrap foreign DbParameter objects to plain values before inserting.
When it happens
Trigger: A custom TursoParameterCollection/DbParameterCollection subclass that stores and returns foreign DbParameter instances (e.g. a wrapping SqlParameter), which Prepare() then reads through the indexer; not producible by the built-in collection's public Add paths.
Common situations: Hand-rolled wrapper collections layered over the ADO.NET types; interop code that shuttles base DbParameter objects between providers; extremely rare with the shipped API surface.
Related errors
- Batch command must be a TursoBatchCommand.
- Connection must be a TursoConnection.
- Transaction must be a TursoTransaction.
- Parameter {parameter.ParameterName} was not found in the SQL
- Parameter at position {parameterIndex} was not found in the
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-20).
Data as JSON: /api/errors/ff78025162d2f7ec.
Report an issue: GitHub.