tursodatabase/turso · error · InvalidOperationException

Value must be set.

Error message

Value must be set.

What it means

This InvalidOperationException is thrown by ValidateManagedParameterValues when a SqliteParameter in the collection has a name but its Value was never assigned (parameter.HasValue is false). Managed execution cannot translate an unset parameter into a Turso wire value.

Source

Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteCommand.cs:529

        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;
            }
            else if (!IsPrefixed(parameterName))

View on GitHub (pinned to 6c72522679)

Solutions

  1. Set the Value property on every parameter before execution
  2. Use Parameters.AddWithValue("@name", value) when creating parameters
  3. For NULL values, explicitly assign Value = DBNull.Value

Example fix

// before
var p = cmd.CreateParameter();
p.ParameterName = "@id";
cmd.Parameters.Add(p);

// after
p.Value = 42; // or DBNull.Value for SQL NULL
cmd.Parameters.Add(p);
Defensive patterns

Strategy: validation

Validate before calling

if (cmd.Parameters.Cast<SqliteParameter>().Any(p => !p.HasValue))
    throw new InvalidOperationException("Bind every parameter before execution.");

Type guard

bool AllBound(SqliteCommand cmd) => cmd.Parameters.Cast<SqliteParameter>().All(p => p.HasValue);

Try / catch

try { cmd.ExecuteNonQuery(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Value must be set"))
{
    // fill values from defaults and retry
}

Prevention

When it happens

Trigger: Creating a SqliteParameter with a ParameterName but no Value (e.g. new SqliteParameter("@x", DbType.Int32) without setting .Value) and executing BuildBatch, PrepareManagedAsync, or ExecuteManagedAsync.

Common situations: Declaring typed parameters up front intending to fill them later but forgetting to set one; conditionally skipping a parameter assignment in a code branch.

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


AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06). Data as JSON: /api/errors/6b093e095c0b326e. Report an issue: GitHub.