tursodatabase/turso · error · InvalidOperationException
Missing value for parameter {parameterName}.
Error message
Missing value for parameter {parameterName}. What it means
The final Prepare() check reports a named placeholder (@name) in the statement that received no value from the collection: GetParameterName returns its name, so the error reads 'Missing value for parameter {name}.' (TursoCommand.cs:199-204).
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoCommand.cs:209
{
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}.");
}
}
_statement?.Dispose();
_statement = preparedStatement;
preparedStatement = null;
}
finally
{
preparedStatement?.Dispose();
}
}
protected override DbParameter CreateDbParameter()
{
return new TursoParameter();
}
View on GitHub (pinned to c1e5928725)
Solutions
- Add a parameter for every @name that appears in the SQL text.
- In dynamic SQL builders, pair each fragment with its value in one helper so they cannot diverge.
- Parse the @-tokens out of the final SQL and assert each has a matching collection entry (see validation snippet).
Example fix
// before
cmd.CommandText = "SELECT * FROM users WHERE id = @id AND tenant = @tenant";
cmd.Parameters.AddWithValue("@id", 42); // @tenant missing -> throws
// after
cmd.CommandText = "SELECT * FROM users WHERE id = @id AND tenant = @tenant";
cmd.Parameters.AddWithValue("@id", 42);
cmd.Parameters.AddWithValue("@tenant", tenantId); Defensive patterns
Strategy: validation
Validate before calling
var required = Regex.Matches(cmd.CommandText, @"(?<![@\w])@(\w+)").Select(m => m.Groups[1].Value).ToHashSet(StringComparer.OrdinalIgnoreCase);
var provided = cmd.Parameters.Cast<TursoParameter>()
.Where(p => !string.IsNullOrEmpty(p.ParameterName))
.Select(p => p.ParameterName.TrimStart('@'));
var missing = required.Except(provided, StringComparer.OrdinalIgnoreCase).ToList();
if (missing.Count > 0)
throw new InvalidOperationException($"Missing values for: {string.Join(", ", missing)}"); Try / catch
try
{
cmd.Prepare();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Missing value for parameter"))
{
// The message names the placeholder; add the matching AddWithValue call and retry.
} Prevention
- Derive the parameter list from the final SQL text, not from a parallel hand-maintained list.
- In SQL builders, add the parameter in the same method that appends the fragment that uses it.
- Run the regex cross-check above in unit tests for every query you ship.
When it happens
Trigger: SQL "SELECT * FROM users WHERE id = @id AND tenant = @tenant" while only @id was added to cmd.Parameters; adding a parameter with an empty ParameterName so it was treated as positional.
Common situations: A new WHERE clause added to SQL without a matching AddWithValue; optional-filter builder code where the SQL fragment and the parameter append are out of sync; prefix or casing mismatch between the SQL token and the collection name.
Related errors
- Parameter {parameter.ParameterName} was not found in the SQL
- Parameter must be of type TursoParameter
- Parameter at position {parameterIndex} was not found in the
- Missing value for parameter at position {i}.
- Turso batch execution is currently supported only for remote
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-20).
Data as JSON: /api/errors/3dddb13d87c61d5b.
Report an issue: GitHub.