dotnet/reactive · error · ArgumentOutOfRangeException
Specified argument was out of the range of valid values…
Error message
Specified argument was out of the range of valid values. (Parameter 'readerCount')
What it means
Memoize(source, readerCount) validates that readerCount is a positive integer. When readerCount is zero or negative, the library throws ArgumentOutOfRangeException naming 'readerCount'. The reader count is the number of enumerators allowed to independently consume the memoized buffer, so a non-positive value is meaningless.
Solutions
- Pass a positive readerCount (>= 1) matching the number of concurrent enumerators you expect.
- Validate/clamp the value before calling: if (readerCount < 1) readerCount = 1;
- If you don't need a bounded reader count, use the parameterless Memoize(source) overload.
Example fix
// before var buffer = source.Memoize(readerCount); // readerCount is 0 // after if (readerCount < 1) readerCount = 1; var buffer = source.Memoize(readerCount);
Defensive patterns
Strategy: validation
Validate before calling
if (readerCount < 1) throw new ArgumentOutOfRangeException(nameof(readerCount), "Must be a positive integer."); var buffer = source.Memoize(readerCount);
Type guard
static bool IsValidReaderCount(int n) => n >= 1;
Try / catch
try { buffer = source.Memoize(readerCount); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "readerCount") { buffer = source.Memoize(1); } Prevention
- Never pass 0 or negative reader counts; default to 1 or the parameterless overload
- Clamp computed values with Math.Max(1, n)
- Beware int fields defaulting to 0 used as reader counts
When it happens
Trigger: Calling EnumerableEx.Memoize(source, readerCount) with readerCount <= 0 (e.g. Memoize(seq, 0) or Memoize(seq, -1)), often when readerCount is computed from a variable that defaults to 0 or comes from unparsed/failed configuration.
Common situations: Passing a default-initialized int (0) before setting the desired reader count; parsing a config value that failed and yielded 0; misreading the parameter as a capacity or buffer size and passing 0 for 'unlimited'.
Related errors
- Cannot access a disposed object. Object name: ''.
- Specified argument was out of the range of valid values…
- new ArgumentOutOfRangeException(nameof(capacity))
- ArgumentOutOfRangeException: capacity
- Specified argument was out of range of valid values…
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/ba149d3cc5145d21.
Report an issue: GitHub.
Appendix: source
Thrown at Ix.NET/Source/System.Interactive/System/Linq/Operators/Memoize.cs:81
/// Creates a buffer with a view over the source sequence, causing a specified number of enumerators to obtain access
/// to all of the sequence's elements without causing multiple enumerations over the source.
/// </summary>
/// <typeparam name="TSource">Source sequence element type.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="readerCount">
/// Number of enumerators that can access the underlying buffer. Once every enumerator has
/// obtained an element from the buffer, the element is removed from the buffer.
/// </param>
/// <returns>
/// Buffer enabling a specified number of enumerators to retrieve all elements from the shared source sequence,
/// without duplicating source enumeration side-effects.
/// </returns>
public static IBuffer<TSource> Memoize<TSource>(this IEnumerable<TSource> source, int readerCount)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (readerCount <= 0)
throw new ArgumentOutOfRangeException(nameof(readerCount));
return new MemoizedBuffer<TSource>(source.GetEnumerator(), readerCount);
}
/// <summary>
/// Memoizes the source sequence within a selector function where a specified number of enumerators can get access to
/// all of the sequence's elements without causing multiple enumerations over the source.
/// </summary>
/// <typeparam name="TSource">Source sequence element type.</typeparam>
/// <typeparam name="TResult">Result sequence element type.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="readerCount">
/// Number of enumerators that can access the underlying buffer. Once every enumerator has
/// obtained an element from the buffer, the element is removed from the buffer.
/// </param>
/// <param name="selector">
/// Selector function with memoized access to the source sequence for a specified number of
/// enumerators.View on GitHub (pinned to 94b5d5ab91)