{"record":{"id":"503d5389244ab41f","repo":"dotnet/reactive","slug":"nameof-index-elementatordefault","errorCode":null,"errorMessage":"nameof(index)","messagePattern":"nameof\\(index\\)","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/ElementAtOrDefault.cs","lineNumber":14,"sourceCode":"﻿// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT License.\n// See the LICENSE file in the project root for more information. \n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TSource> ElementAtOrDefault<TSource>(this IAsyncObservable<TSource> source, int index)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (index < 0)\n                throw new ArgumentOutOfRangeException(nameof(index));\n\n            return Create(\n                source,\n                index,\n                static (source, index, observer) => source.SubscribeSafeAsync(AsyncObserver.ElementAtOrDefault(observer, index)));\n        }\n    }\n\n    public partial class AsyncObserver\n    {\n        public static IAsyncObserver<TSource> ElementAtOrDefault<TSource>(IAsyncObserver<TSource> observer, int index)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (index < 0)\n                throw new ArgumentOutOfRangeException(nameof(index));\n\n            return Create<TSource>(","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/ElementAtOrDefault.cs#L1-L32","documentation":"This is an ArgumentOutOfRangeException thrown by AsyncObservable.ElementAtOrDefault when the index parameter is negative. Even though the operator yields a default value instead of an error for out-of-range indexes on a live sequence, the index itself must still be a non-negative ordinal, so it is validated synchronously at the call.","triggerScenarios":"Calling source.ElementAtOrDefault(n) with n < 0; commonly from a parsed/decimal index that lost its sign check, or a computed value like pos - 1 where pos == 0.","commonSituations":"Mapping external indexes (UI selection, API parameters) directly into ElementAtOrDefault without clamping; arithmetic that underflows; treating -1 as a sentinel for 'last' which this API does not support.","solutions":["Clamp or validate: if (index < 0) handle separately before calling","Convert sentinels like -1 explicitly (e.g. take the last element via a different operator)","Fix the upstream computation that produced the negative index"],"exampleFix":"// before\nvar item = source.ElementAtOrDefault(idx); // idx = -1 sentinel\n// after\nvar item = idx >= 0 ? source.ElementAtOrDefault(idx) : default(TSource);","handlingStrategy":"validation","validationCode":"if (index < 0) throw new ArgumentOutOfRangeException(nameof(index));\nvar result = source.ElementAtOrDefault(index);","typeGuard":"bool IsValidElementIndex(int i) => i >= 0;","tryCatchPattern":"try { var result = source.ElementAtOrDefault(index); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"index\") { /* clamp index or use default */ }","preventionTips":["Clamp external indexes: Math.Max(0, index) before the call","Do not use -1 as a 'last element' sentinel with this API; convert explicitly","Validate indexes parsed from config or API payloads"],"tags":["argument-out-of-range","async-rx","index"],"backgroundTag":"argument-out-of-range","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}