dotnet/reactive · error · InvalidOperationException
Element no longer available in the buffer.
Error message
Element no longer available in the buffer.
What it means
RefCountList<T> is an internal ref-counted circular buffer used by buffering operators such as Memoize/Buffer with reference semantics. Its indexer decrements the reference count for index i and removes entries whose count reaches zero. If the entry is already gone, the buffer's contract (Debug.Assert(i < Count)) was violated by the caller, and the list throws InvalidOperationException("Element no longer available in the buffer.") instead of returning the value.
Solutions
- Increase the buffer capacity/size passed to the buffering operator so elements live long enough.
- Ensure each consumer enumerates its own enumerator rather than sharing one enumerator across loops.
- Avoid re-enumerating a shared buffered sequence more times than supported; memoize materialized results (ToList) when reuse is needed.
- This is an internal invariant breach — if reproducible with normal usage, file a bug against System.Interactive with a minimal repro.
- Serialize access if multiple threads enumerate the shared buffer concurrently.
Defensive patterns
Strategy: fallback
Try / catch
try { var item = buffer[i]; }
catch (InvalidOperationException ex) when (ex.Message.Contains("no longer available")) {
// re-enumerate from the original source or re-memoize
} Prevention
- Size buffers to cover the number of overlapping consumers/re-enumerations.
- Don't share a single enumerator across loops; call GetEnumerator per consumer.
- Materialize (ToList) if you need unbounded replay of buffered data.
- Keep consumer progress within the buffer's live window.
- Report genuine invariant violations as library bugs with a repro.
When it happens
Trigger: Enumerating a buffered/shared sequence more times or in more overlapping passes than the buffer capacity/ref-counting allows; reading an index after its references were exhausted (item evicted from the circular buffer); concurrent enumeration of the shared buffer from multiple consumers.
Common situations: Multiple foreach loops over one Memoize'd/buffered sequence with too small a buffer, re-enumerating an enumerator past eviction, or consumers of different speeds over a shared buffer sequence.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Specified argument was out of the range of valid values. (Pa
- Cannot access a disposed object. Object name: ''.
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'source')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/436119c6304d8c80.
Report an issue: GitHub.
Appendix: source
Thrown at Ix.NET/Source/System.Interactive/System/Linq/RefCountList.cs:27
{
internal sealed class RefCountList<T>(int readerCount) : IRefCountList<T>
{
private readonly IDictionary<int, RefCount> _list = new Dictionary<int, RefCount>();
public int ReaderCount { get; set; } = readerCount;
public void Clear() => _list.Clear();
public int Count { get; private set; }
public T this[int i]
{
get
{
Debug.Assert(i < Count);
if (!_list.TryGetValue(i, out var res))
throw new InvalidOperationException("Element no longer available in the buffer.");
var val = res.Value;
if (--res.Count == 0)
{
_list.Remove(i);
}
return val;
}
}
public void Add(T item)
{
_list[Count] = new RefCount(item, ReaderCount);
Count++;
}View on GitHub (pinned to 94b5d5ab91)