{"record":{"id":"ae826b3753f155cd","repo":"dotnet/csharplang","slug":"array-must-contain-a-single-element","errorCode":null,"errorMessage":"Array must contain a single element.","messagePattern":"Array must contain a single element\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"proposals/csharp-10.0/caller-argument-expression.md","lineNumber":43,"sourceCode":"```\n\nWhen 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.\n\nThis 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.\n\nWhile 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\n\n```csharp\nT Single<T>(this T[] array)\n{\n    if (array == null)\n    {\n        throw new ArgumentNullException(nameof(array));\n    }\n\n    if (array.Length != 1)\n    {\n        throw new ArgumentException(\"Array must contain a single element.\", nameof(array));\n    }\n\n    return array[0];\n}\n```\n\nNotice that `nameof(array)` must be passed to each exception, although it's already clear from context which argument is invalid.\n\n## Detailed design\n[design]: #detailed-design\n\nIn 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\n\n```csharp\npublic static class Debug\n{\n    public static void Assert(bool condition, [CallerArgumentExpression(\"condition\")] string message = null);\n}","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/dotnet/csharplang/blob/05eb4800fc3dc76259ccd49ac01f1eeb49222380/proposals/csharp-10.0/caller-argument-expression.md#L25-L61","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nT value = array.Single<T>();\n\n// after\nif (array is null) throw new ArgumentNullException(nameof(array));\nif (array.Length != 1) throw new ArgumentException(\"Array must contain a single element.\", nameof(array));\nT value = array[0];","handlingStrategy":"validation","validationCode":"static T SafeSingle<T>(T[] array)\n{\n    if (array is null) throw new ArgumentNullException(nameof(array));\n    if (array.Length != 1)\n        throw new InvalidOperationException($\"Expected exactly one element, got {array.Length}.\");\n    return array[0];\n}","typeGuard":"static bool HasSingle<T>(T[] array) => array is { Length: 1 };","tryCatchPattern":"try { T value = array.Single(); }\ncatch (InvalidOperationException ex) when (array is null || array.Length != 1)\n{\n    // log and apply single-or-default fallback\n}","preventionTips":["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."],"tags":["array","argument-validation","linq","csharp"],"backgroundTag":null,"analyzedSha":"05eb4800fc3dc76259ccd49ac01f1eeb49222380","analyzedAt":"2026-08-13T17:44:03.908Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}