{"record":{"id":"3dddb13d87c61d5b","repo":"tursodatabase/turso","slug":"missing-value-for-parameter-parametername","errorCode":null,"errorMessage":"Missing value for parameter {parameterName}.","messagePattern":"Missing value for parameter (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoCommand.cs","lineNumber":209,"sourceCode":"                {\n                    var parameterIndex = i + 1;\n                    if (parameterIndex > parameterCount)\n                        throw new InvalidOperationException($\"Parameter at position {parameterIndex} was not found in the SQL statement.\");\n\n                    TursoBindings.BindParameter(preparedStatement, parameterIndex, parameter.ToValue());\n                    boundParameters[parameterIndex] = true;\n                }\n            }\n\n            for (var i = 1; i <= parameterCount; i++)\n            {\n                if (!boundParameters[i])\n                {\n                    var parameterName = TursoBindings.GetParameterName(preparedStatement, i);\n                    throw new InvalidOperationException(\n                        parameterName is null\n                            ? $\"Missing value for parameter at position {i}.\"\n                            : $\"Missing value for parameter {parameterName}.\");\n                }\n            }\n\n            _statement?.Dispose();\n            _statement = preparedStatement;\n            preparedStatement = null;\n        }\n        finally\n        {\n            preparedStatement?.Dispose();\n        }\n    }\n\n    protected override DbParameter CreateDbParameter()\n    {\n        return new TursoParameter();\n    }\n","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/bindings/dotnet/src/Turso.Data/TursoCommand.cs#L191-L227","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\ncmd.CommandText = \"SELECT * FROM users WHERE id = @id AND tenant = @tenant\";\ncmd.Parameters.AddWithValue(\"@id\", 42); // @tenant missing -> throws\n\n// after\ncmd.CommandText = \"SELECT * FROM users WHERE id = @id AND tenant = @tenant\";\ncmd.Parameters.AddWithValue(\"@id\", 42);\ncmd.Parameters.AddWithValue(\"@tenant\", tenantId);","handlingStrategy":"validation","validationCode":"var required = Regex.Matches(cmd.CommandText, @\"(?<![@\\w])@(\\w+)\").Select(m => m.Groups[1].Value).ToHashSet(StringComparer.OrdinalIgnoreCase);\nvar provided = cmd.Parameters.Cast<TursoParameter>()\n    .Where(p => !string.IsNullOrEmpty(p.ParameterName))\n    .Select(p => p.ParameterName.TrimStart('@'));\nvar missing = required.Except(provided, StringComparer.OrdinalIgnoreCase).ToList();\nif (missing.Count > 0)\n    throw new InvalidOperationException($\"Missing values for: {string.Join(\", \", missing)}\");","typeGuard":null,"tryCatchPattern":"try\n{\n    cmd.Prepare();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Missing value for parameter\"))\n{\n    // The message names the placeholder; add the matching AddWithValue call and retry.\n}","preventionTips":["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."],"tags":["dotnet","ado-net","tursodb","parameters","named-parameters"],"backgroundTag":"missing-sql-parameter","analyzedSha":"c1e59287258d99b309e362a63f48822256e2f65f","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}