tursodatabase/turso · error · InvalidOperationException

Parameter {parameter.ParameterName} was not found in the SQL

Error message

Parameter {parameter.ParameterName} was not found in the SQL statement.

What it means

While binding named parameters, TursoBindings.BindNamedParameter returns the 1-based index of the matching SQL placeholder or 0 when the prepared statement contains no parameter with that name (TursoCommand.cs:176-180). A zero result makes Prepare throw InvalidOperationException naming the offending parameter — the collection and the SQL text disagree on a name.

Source

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

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

            for (var i = 1; i <= parameterCount; i++)
            {
                if (!boundParameters[i])
                {

View on GitHub (pinned to c1e5928725)

Solutions

  1. Match the ParameterName exactly to the placeholder in the SQL, including the @ prefix.
  2. Keep the AddWithValue call physically next to the SQL it serves, or derive parameter names from the SQL text.
  3. Pick one style per statement: all named (@x) placeholders with named parameters, or all ? with positional parameters.

Example fix

// before
cmd.CommandText = "SELECT * FROM users WHERE id = @user";
cmd.Parameters.AddWithValue("@usr", 42); // name mismatch -> throws

// after
cmd.CommandText = "SELECT * FROM users WHERE id = @user";
cmd.Parameters.AddWithValue("@user", 42);
Defensive patterns

Strategy: validation

Validate before calling

var names = Regex.Matches(cmd.CommandText, @"(?<![@\w])@(\w+)").Select(m => m.Groups[1].Value).ToHashSet(StringComparer.OrdinalIgnoreCase);
foreach (TursoParameter p in cmd.Parameters)
{
    if (!string.IsNullOrEmpty(p.ParameterName) && !names.Contains(p.ParameterName.TrimStart('@')))
        throw new InvalidOperationException($"{p.ParameterName} does not appear in the SQL text.");
}

Try / catch

try
{
    cmd.Prepare();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("was not found in the SQL statement"))
{
    // Read the parameter name from the message and align it with the SQL placeholder.
}

Prevention

When it happens

Trigger: cmd.Parameters.AddWithValue("@usr", 42) while the SQL uses @user (typo or prefix style mismatch); supplying named parameters to SQL written with positional ? placeholders; SQL edited after the parameter code was written.

Common situations: Typo or @/no-prefix inconsistency between the AddWithValue call and the SQL string; refactors that rename a column/parameter in SQL but not in code; mixed named/positional styles inside one statement.

Related errors


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