SqlParameterCollection
SqlParameter
.NET
Error Handling
Database Programming

SqlParameterCollection only accepts non-null SqlParameter type objects, not String objects

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

This error means you are adding the wrong kind of object to SqlCommand.Parameters. The collection accepts SqlParameter objects, but your code is passing a plain string instead. In practice, this usually happens because the wrong Add overload was called or because someone tried to add parameter values without creating actual parameter objects.

What the Collection Expects

SqlParameterCollection belongs to ADO.NET and stores parameter definitions for a SQL command.

A correct example looks like this:

csharp
1using System.Data.SqlClient;
2
3var command = new SqlCommand("SELECT * FROM Users WHERE Id = @Id");
4command.Parameters.Add(new SqlParameter("@Id", 42));

Here the collection receives a real SqlParameter object, which is what it expects.

A Common Wrong Pattern

The error often appears when code does something like this:

csharp
command.Parameters.Add("@Id");

That adds a string object, not a SqlParameter instance, so the collection rejects it.

The fix is to use the overload that creates or supplies a parameter correctly.

Correct Ways to Add Parameters

One clear approach is to create the parameter explicitly.

csharp
command.Parameters.Add(new SqlParameter("@Id", 42));

Another common option is AddWithValue.

csharp
command.Parameters.AddWithValue("@Id", 42);

And another is to create the parameter with type information.

csharp
command.Parameters.Add("@Id", System.Data.SqlDbType.Int).Value = 42;

This third form is often better when you want explicit control over SQL types.

Why the Wrong Overload Happens

ADO.NET has several Add overloads, which can make the API easy to misuse if you rely on guesswork.

Developers often assume that passing a string is enough because they are thinking of the parameter name, but the collection needs more than the name. It needs either:

  • a real SqlParameter object
  • or an overload that knows how to construct one properly

That is why reading the overload signature matters.

Full Runnable Example

csharp
1using System;
2using System.Data;
3using System.Data.SqlClient;
4
5class Demo {
6    static void Main() {
7        using var command = new SqlCommand("SELECT * FROM Users WHERE Id = @Id AND Name = @Name");
8        command.Parameters.Add("@Id", SqlDbType.Int).Value = 42;
9        command.Parameters.Add("@Name", SqlDbType.NVarChar, 100).Value = "Alice";
10
11        foreach (SqlParameter p in command.Parameters) {
12            Console.WriteLine($"{p.ParameterName} = {p.Value}");
13        }
14    }
15}

This avoids the error because every item added to the collection is a proper parameter.

Why Explicit Types Can Be Better

AddWithValue is convenient, but it can infer a SQL type you did not intend. That is why many teams prefer the explicit typed overloads for production database code.

So the real best practice is often:

  • use typed Add overloads when type precision matters
  • use AddWithValue only when the inferred type is obviously correct

Common Pitfalls

The biggest mistake is calling Parameters.Add("@Name") and assuming the collection will infer the rest.

Another mistake is using the parameter name string where the API expects a SqlParameter object.

A third issue is fixing the error with AddWithValue everywhere without considering whether the inferred SQL type is appropriate.

Summary

  • The error means a string was added where SqlParameterCollection expected a SqlParameter
  • Use new SqlParameter(...), typed Add(...), or AddWithValue(...) correctly
  • The problem usually comes from calling the wrong Add overload
  • Explicit parameter types are often better than relying on inference
  • Parameterized commands should be built from real parameter objects, not plain strings

Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design