louthy/language-ext · error · ArgumentException
Can't create an IterableNE from an empty sequence
Error message
Can't create an IterableNE from an empty sequence
What it means
IterableNE is LanguageExt's non-empty iterable type: it structurally guarantees at least one element (head + tail). createRange<A>(IAsyncEnumerable<A>) must uphold that invariant, so when the async source yields no elements it throws ArgumentException("Can't create an IterableNE from an empty sequence").
Solutions
- Check emptiness before calling: materialize to a list and use Count == 0 guard, or use IteratorAsync.from(items).IsEmpty first
- If emptiness is legal in your domain, return Option<IterableNE<A>>/Iterable (possibly-empty) instead of IterableNE
- Provide a default element or fallback sequence when the source is empty
- Throw/propagate a domain-specific error with context (which source was empty) rather than the bare ArgumentException
Example fix
// before
var ne = IterableNE.createRange(items); // throws when items is empty
// after
var arr = await items.ToListAsync();
var ne = arr.Count == 0
? IterableNE.createRange(fallback)
: IterableNE.createRange(arr.ToAsyncEnumerable()); Defensive patterns
Strategy: validation
Validate before calling
public static async Task<bool> IsEmptyAsync<T>(IAsyncEnumerable<T> src)
{
await foreach (var _ in src) return false;
return true;
}
// call before createRange:
// if (await IsEmptyAsync(items)) { /* handle empty */ } Type guard
async Task<Option<IterableNE<A>>> TryCreateRange<A>(IAsyncEnumerable<A> items)
{
var iter = IteratorAsync.from(items);
if (await iter.IsEmpty) return Option<IterableNE<A>>.None;
return await IterableNE.createRange(items);
} Try / catch
try { var ne = await IterableNE.createRange(items); }
catch (ArgumentException ex) when (ex.Message.Contains("empty sequence"))
{
// decide: default value, Option.None, or rethrow with context
} Prevention
- Never assume async sources are non-empty; always probe IsEmpty first
- Prefer Iterable<A> when emptiness is a legitimate domain state
- Materialize with a Count/Any check before building non-empty types
- Add tests with empty inputs for all IterableNE constructions
- Encode emptiness as Option<IterableNE<A>> at API boundaries
When it happens
Trigger: Calling IterableNE.createRange on an IAsyncEnumerable<A> whose first await iter.IsEmpty is true — i.e. the source produces zero items (public API createRange in IterableNE.Module.cs:119).
Common situations: Querying a database/collection that turned out to be empty; filtering removed all elements upstream; passing an empty array/List.AsEnumerable() to createRange; assuming a source is non-empty after refactoring; first-element access on empty streams.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Cannot create an IterableNE from an empty span
- Nil iterator has no head
- Nil iterator has no head
- IndexOutOfRangeException
- Key doesn't exist in map
AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15).
Data as JSON: /api/errors/9510f3f18f367879.
Report an issue: GitHub.
Appendix: source
Thrown at LanguageExt.Core/Immutable Collections/IterableNE/IterableNE.Module.cs:119
var iter = Iterator.from(items);
if (iter.IsEmpty) return None;
var head = iter.Head;
var tail = iter.Tail.AsIterable();
return new IterableNE<A>(head, tail);
}
/// <summary>
/// Create a sequence from an initial set of items
/// </summary>
/// <param name="items">Items</param>
/// <returns>sequence</returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IO<IterableNE<A>> createRange<A>(IAsyncEnumerable<A> items) =>
IO.liftVAsync(async _ =>
{
var iter = IteratorAsync.from(items);
if (await iter.IsEmpty) throw new ArgumentException("Can't create an IterableNE from an empty sequence");
var head = await iter.Head;
var tail = (await iter.Tail).AsIterable();
return new IterableNE<A>(head, tail);
});
/// <summary>
/// Create a sequence from an initial set of items
/// </summary>
/// <param name="items">Items</param>
/// <returns>sequence</returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IO<IterableNE<A>> createRange<A>(Iterable<A> items)
{
return IO.liftVAsync(_ => items.IsAsync
? async()
: sync());
View on GitHub (pinned to 2f0e362824)