dotnet/csharplang · error · ArgumentException
Array must contain a single element.
Error message
Array must contain a single element.
What it means
Thrown by an illustrative `Single<T>(this T[] array)` extension method when the supplied array does not contain exactly one element. The check is shown in the caller-argument-expression proposal as the 'traditional' argument-validation style that the feature is meant to reduce. A null array is handled separately by ArgumentNullException; this exception is specifically the length != 1 case.
Source
Thrown at proposals/csharp-10.0/caller-argument-expression.md:43
```
When one of the asserts fail, only the filename, line number, and method name will be provided in the stack trace. The developer will not be able to tell which assert failed from this information-- they will have to open the file and navigate to the provided line number to see what went wrong.
This is also the reason testing frameworks have to provide a variety of assert methods. With xUnit, `Assert.True` and `Assert.False` are not frequently used because they do not provide enough context about what failed.
While the situation is a bit better for argument validation because the names of invalid arguments are shown to the developer, the developer must pass these names to exceptions manually. If the above example were rewritten to use traditional argument validation instead of `Debug.Assert`, it would look like
```csharp
T Single<T>(this T[] array)
{
if (array == null)
{
throw new ArgumentNullException(nameof(array));
}
if (array.Length != 1)
{
throw new ArgumentException("Array must contain a single element.", nameof(array));
}
return array[0];
}
```
Notice that `nameof(array)` must be passed to each exception, although it's already clear from context which argument is invalid.
## Detailed design
[design]: #detailed-design
In the above examples, including the string `"array != null"` or `"array.Length == 1"` in the assert message would help the developer determine what failed. Enter `CallerArgumentExpression`: it's an attribute the framework can use to obtain the string associated with a particular method argument. We would add it to `Debug.Assert` like so
```csharp
public static class Debug
{
public static void Assert(bool condition, [CallerArgumentExpression("condition")] string message = null);
}View on GitHub (pinned to 05eb4800fc)
Solutions
- Guarantee exactly one element before calling Single: check `array.Length == 1` (or use LINQ `Single()` only after confirming one match).
- If zero-or-one is acceptable, switch to a FirstOrDefault-style read and handle the null/missing case explicitly.
- If multiple is acceptable, use First/Last or index `array[0]` after a length guard.
- Fix the upstream producer so it cannot emit an empty or multi-element array.
Example fix
// before
T value = array.Single<T>();
// after
if (array is null) throw new ArgumentNullException(nameof(array));
if (array.Length != 1) throw new ArgumentException("Array must contain a single element.", nameof(array));
T value = array[0]; Defensive patterns
Strategy: validation
Validate before calling
static T SafeSingle<T>(T[] array)
{
if (array is null) throw new ArgumentNullException(nameof(array));
if (array.Length != 1)
throw new InvalidOperationException($"Expected exactly one element, got {array.Length}.");
return array[0];
} Type guard
static bool HasSingle<T>(T[] array) => array is { Length: 1 }; Try / catch
try { T value = array.Single(); }
catch (InvalidOperationException ex) when (array is null || array.Length != 1)
{
// log and apply single-or-default fallback
} Prevention
- Check `array is { Length: 1 }` before treating an array as a singleton.
- Prefer FirstOrDefault with an explicit missing-value branch when zero elements is valid.
- Ensure the array's producer cannot emit empty or multi-element results.
When it happens
Trigger: Calling `array.Single()` on an array whose Length is 0 (empty) or >= 2. Passing a collection that has been filtered/cleared so it no longer has exactly one item.
Common situations: LINQ-style Single usage on results of a query that returned zero or multiple matches; defensive code that assumes a singleton array after deserialization; arrays whose contents were mutated between population and the Single call.
Related errors
- {argumentExpression} ({argument}) cannot be less than {lowEx
- {argumentExpression} ({argument}) cannot be greater than {hi
- Index must not be negative.
- Empty names not allowed
AI-assisted analysis of dotnet/csharplang@05eb4800fc (2026-08-13).
Data as JSON: /api/errors/ae826b3753f155cd.
Report an issue: GitHub.