programming
exception-handling
software-development
debugging
.NET

Sequence contains more than one element

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

The "Sequence contains more than one element" exception is one of the most common runtime errors in C# LINQ code. It is thrown by the Single() and SingleOrDefault() methods when they find more than one element matching the query condition. This article explains why it happens, how to fix it, and which LINQ method to use based on your actual requirements.

Why This Exception Occurs

The Single() method expresses a strong assertion: "there is exactly one element in this sequence that matches my condition." If the sequence has zero elements or more than one, the assertion is violated and LINQ throws an InvalidOperationException.

csharp
1var numbers = new List<int> { 1, 2, 3, 2, 4 };
2
3// This throws: "Sequence contains more than one element"
4var result = numbers.Single(n => n == 2);

There are two values of 2 in the list, so Single() cannot determine which one to return. Rather than silently picking one (which would mask a data integrity issue), it throws an exception.

Single() vs. SingleOrDefault() vs. First() vs. FirstOrDefault()

Understanding the four related methods is essential for choosing the right one:

csharp
var users = dbContext.Users.Where(u => u.Role == "Admin").ToList();
Method0 elements1 element2+ elements
Single()ThrowsReturns itThrows
SingleOrDefault()Returns defaultReturns itThrows
First()ThrowsReturns itReturns first
FirstOrDefault()Returns defaultReturns itReturns first

The key difference: Single methods throw when there are multiple matches. First methods simply return the first match and ignore the rest.

Common Scenarios That Cause This Error

Duplicate Data

The most frequent cause is unexpected duplicate records in a database:

csharp
// You expect one user per email, but the database has duplicates
var user = dbContext.Users.Single(u => u.Email == "[email protected]");
// Throws if two rows have the same email

Missing or Overly Broad Filter

Sometimes the predicate is not specific enough to narrow down to one result:

csharp
// Looking for a "default" setting, but multiple settings are marked as default
var setting = dbContext.Settings.Single(s => s.IsDefault == true);

Querying Without a Predicate

Calling Single() on a collection without a predicate asserts that the entire collection has exactly one element:

csharp
var items = new List<string> { "a", "b" };
var item = items.Single(); // Throws: more than one element

How to Fix It

Option 1: Use First() or FirstOrDefault() If Duplicates Are Acceptable

If having multiple matches is normal and you just want any one of them:

csharp
var user = dbContext.Users.First(u => u.Role == "Admin");
// Returns the first admin found, no exception for multiples

Use FirstOrDefault() if the sequence might be empty and you want null instead of an exception:

csharp
1var user = dbContext.Users.FirstOrDefault(u => u.Role == "Admin");
2if (user == null)
3{
4    Console.WriteLine("No admin found");
5}

Option 2: Fix the Data If Duplicates Are a Bug

If duplicates indicate a data integrity problem, the right fix is at the data level. Add a unique constraint to prevent future duplicates:

sql
ALTER TABLE Users ADD CONSTRAINT UQ_Users_Email UNIQUE (Email);

Then clean up existing duplicates before using Single() again.

Option 3: Add a More Specific Predicate

Narrow your query so it truly returns one result:

csharp
// Instead of filtering by role alone, add more conditions
var user = dbContext.Users.Single(u => u.Email == "[email protected]" && u.IsActive);

Option 4: Use Where() and Handle Multiple Results Explicitly

If you want full control, use Where() and handle the count yourself:

csharp
1var admins = dbContext.Users.Where(u => u.Role == "Admin").ToList();
2
3if (admins.Count == 0)
4{
5    Console.WriteLine("No admin found");
6}
7else if (admins.Count == 1)
8{
9    ProcessAdmin(admins[0]);
10}
11else
12{
13    Console.WriteLine($"Warning: found {admins.Count} admins, expected 1");
14    // Handle accordingly
15}

SingleOrDefault() Still Throws for Multiple Elements

A common misconception is that SingleOrDefault() is the "safe" version of Single(). It only handles the empty-sequence case by returning default (typically null). It still throws for multiple elements:

csharp
1var numbers = new List<int> { 2, 2 };
2
3// This also throws: "Sequence contains more than one element"
4var result = numbers.SingleOrDefault(n => n == 2);

If you want safety from both empty sequences and multiple matches, FirstOrDefault() is the method you need.

Common Pitfalls

  • Using Single() for lookups that should use First(): If your business logic does not require uniqueness, do not use Single(). It adds a constraint that the data may not satisfy.
  • Assuming SingleOrDefault() handles duplicates: It does not. You still get the exception for multiple matches.
  • Not ordering when using First(): Without OrderBy(), First() returns whichever element the database or LINQ provider happens to return first, which can vary between runs.
  • Clean test data masking the issue: If Single() works in tests but fails in production, your test data is too clean. Add edge cases with duplicates.

Summary

The "Sequence contains more than one element" exception means your Single() or SingleOrDefault() call found multiple matching elements when it expected at most one. If duplicates are acceptable, switch to First() or FirstOrDefault(). If duplicates are a bug, fix the data and add unique constraints. Always pair First() with OrderBy() for deterministic results. Choose the LINQ method that matches your actual data guarantees, not the one that sounds most convenient.


Course illustration
Course illustration

All Rights Reserved.