tursodatabase/turso · error · InvalidOperationException
ParameterName must be set.
Error message
ParameterName must be set.
What it means
This InvalidOperationException is thrown by ValidateManagedParameterValues when a SqliteParameter in the command's Parameters collection has an empty or null ParameterName. Managed Turso commands address parameters by name, so every parameter must have an explicit name before execution.
Source
Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteCommand.cs:527
if (statement.FirstKeyword != "ROLLBACK")
return false;
var sql = statement.Sql.TrimStart();
if (!sql.StartsWith("ROLLBACK", StringComparison.OrdinalIgnoreCase))
return false;
sql = sql["ROLLBACK".Length..].TrimStart();
if (sql.StartsWith("TRANSACTION", StringComparison.OrdinalIgnoreCase))
sql = sql["TRANSACTION".Length..].TrimStart();
return sql.StartsWith("TO", StringComparison.OrdinalIgnoreCase);
}
internal void ValidateManagedParameterValues()
{
for (var index = 0; index < Parameters.Count; index++)
{
var parameter = Parameters[index];
if (string.IsNullOrEmpty(parameter.ParameterName))
throw new InvalidOperationException(Properties.Resources.RequiresSet(nameof(parameter.ParameterName)));
if (!parameter.HasValue)
throw new InvalidOperationException(Properties.Resources.RequiresSet(nameof(parameter.Value)));
}
}
internal void AddManagedParameters(
global::Turso.TursoCommand command,
ManagedSqliteStatement statement)
{
var mapped = new Dictionary<string, SqliteParameter>(StringComparer.Ordinal);
for (var index = 0; index < Parameters.Count; index++)
{
var parameter = Parameters[index];
var parameterName = parameter.ParameterName;
string? matchedName = null;
if (statement.ParameterNames.Contains(parameterName, StringComparer.Ordinal))
{
matchedName = parameterName;View on GitHub (pinned to 6c72522679)
Solutions
- Set ParameterName explicitly on each SqliteParameter before executing the command
- Use Named parameters in CommandText (e.g. @name) and add parameters with matching names via cmd.Parameters.AddWithValue("@name", value)
- Only use unnamed positional parameters on local (non-managed) connections
Example fix
// before
cmd.Parameters.Add(new SqliteParameter(42));
// after
cmd.Parameters.Add(new SqliteParameter("@id", 42)); Defensive patterns
Strategy: validation
Validate before calling
foreach (SqliteParameter p in cmd.Parameters)
if (!p.HasValue)
throw new InvalidOperationException($"Parameter '{p.ParameterName}' has no value."); Type guard
bool HasValue(SqliteParameter p) => p.HasValue;
Try / catch
try { cmd.ExecuteNonQuery(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Value must be set"))
{
// set missing Value or DBNull.Value and retry
} Prevention
- Prefer AddWithValue over split name/value assignment
- Explicitly assign DBNull.Value instead of skipping assignments
When it happens
Trigger: Adding SqliteParameter objects with only a Value (positional style, e.g. new SqliteParameter(value) or AddWithValue variants that leave the name empty) and then executing BuildBatch, PrepareManagedAsync, or ExecuteManagedAsync on a managed (direct remote / embedded replica) connection.
Common situations: Porting embedded SQLite code that used '?' positional parameters and unnamed parameter objects to managed Turso remote connections; copying parameters from another command where names were never assigned.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Value must be set.
- Parameter {value} not found
- Parameter {parameterName} not found
- Parameter {value} is not a TursoParameter
- Parameter must be of type TursoParameter
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06).
Data as JSON: /api/errors/43790b1bdb780cd6.
Report an issue: GitHub.