dotnet/reactive · error · ArgumentOutOfRangeException
nameof(index)
Error message
nameof(index)
What it means
Thrown by ElementAt(source, index) when index is negative. The operator throws ArgumentOutOfRangeException naming index because a negative position can never match an element. Unlike ElementAtOrDefault, ElementAt treats both a null source and a negative index as hard errors.
Solutions
- Validate index >= 0 before calling ElementAt
- Clamp negative computed values to 0 or skip the call when index < 0
- Use ElementAtOrDefault for callers that want a default instead of an exception for missing positions (still validate non-negative first)
- When the index comes from external input (config, CLI, HTTP), parse and range-check it explicitly
Example fix
// before
int idx = items.Length - 1 - offset; // can be -1
var item = AsyncObservable.ElementAt(source, idx); // throws when idx < 0
// after
int idx = items.Length - 1 - offset;
if (idx >= 0)
{
var item = AsyncObservable.ElementAt(source, idx);
} Defensive patterns
Strategy: validation
Validate before calling
if (index < 0) throw new InvalidOperationException("ElementAt requires a non-negative index");
var item = AsyncObservable.ElementAt(source, index); Type guard
bool IsValidIndex(int i) => i >= 0;
Try / catch
try
{
var item = AsyncObservable.ElementAt(source, index);
}
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "index")
{
// negative index; fall back to a default value
item = default;
} Prevention
- Range-check any externally supplied index (config, CLI, HTTP) before calling ElementAt
- Use ElementAtOrDefault when absence of an element should yield a default rather than throw
- Guard computed indices from decrements/offsets that can go negative
- Clamp: index = Math.Max(0, index) when a non-negative position is guaranteed by domain rules
When it happens
Trigger: Calling ElementAt(source, -1) or with an index computed from an unseeded counter, a failed parse, or an off-by-one decrement that went below zero.
Common situations: User-supplied indices parsed from config or CLI without validation; loop variables decremented before the call; arithmetic on empty collections (last - 1) yielding -1.
Related errors
- nameof(source)
- Specified argument was out of the range of valid values…
- count
- duration
- Value cannot be null. (Parameter 'onCompletedAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/632723b1aff8e3a0.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/ElementAt.cs:16
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information.
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> ElementAt<TSource>(this IAsyncObservable<TSource> source, int index)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index));
return Create(
source,
index,
static (source, index, observer) => source.SubscribeSafeAsync(AsyncObserver.ElementAt(observer, index)));
}
}
public partial class AsyncObserver
{
public static IAsyncObserver<TSource> ElementAt<TSource>(IAsyncObserver<TSource> observer, int index)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index));
return Create<TSource>(View on GitHub (pinned to 94b5d5ab91)