tursodatabase/turso · error · InvalidOperationException

Parameter at position {parameterIndex} was not found in the

Error message

Parameter at position {parameterIndex} was not found in the SQL statement.

What it means

Positional (nameless) parameters are bound by collection order: the i-th parameter maps to placeholder index i+1 (TursoCommand.cs:184-188). If the collection holds more positional parameters than the statement has placeholders, i+1 exceeds GetParameterCount and Prepare throws InvalidOperationException reporting the offending position.

Source

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

            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;
                }
            }

            for (var i = 1; i <= parameterCount; i++)
            {
                if (!boundParameters[i])
                {
                    var parameterName = TursoBindings.GetParameterName(preparedStatement, i);
                    throw new InvalidOperationException(
                        parameterName is null
                            ? $"Missing value for parameter at position {i}."
                            : $"Missing value for parameter {parameterName}.");
                }
            }

View on GitHub (pinned to c1e5928725)

Solutions

  1. Make the count of nameless parameters exactly equal the number of ? placeholders in the SQL.
  2. Call cmd.Parameters.Clear() before re-running a command with different SQL or parameter sets.
  3. Prefer named parameters when SQL is built dynamically so count/order drift cannot silently shift bindings.

Example fix

// before
cmd.CommandText = "INSERT INTO t VALUES (?, ?)"; // 2 placeholders
cmd.Parameters.AddWithValue(null, a);
cmd.Parameters.AddWithValue(null, b);
cmd.Parameters.AddWithValue(null, c); // 3rd positional -> throws at position 3

// after
cmd.CommandText = "INSERT INTO t VALUES (?, ?)";
cmd.Parameters.AddWithValue(null, a);
cmd.Parameters.AddWithValue(null, b);
Defensive patterns

Strategy: validation

Validate before calling

var positional = cmd.Parameters.Cast<TursoParameter>().Count(p => string.IsNullOrEmpty(p.ParameterName));
var placeholders = CountPlaceholders(cmd.CommandText); // count '?' outside string literals
if (positional > placeholders)
    throw new InvalidOperationException($"{positional} positional parameters but only {placeholders} '?' placeholders.");

Prevention

When it happens

Trigger: SQL "INSERT INTO t VALUES (?, ?)" with three nameless parameters added to Parameters; a loop that appends positional parameters without matching the placeholder count.

Common situations: Parameters added in a loop over a list whose length drifted from the SQL; a reused command object carrying leftover positional parameters; dynamic SQL that dropped a placeholder during editing.

Related errors


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