bazelbuild/bazel · error · EvalException
expected at least one item
Error message
expected at least one item
What it means
Thrown by the built-in min()/max() when the iterable is empty. Guava's Ordering.max(Iterable) raises NoSuchElementException on an empty input; MethodLibrary converts it to EvalException with the message 'expected at least one item'. Starlark's min/max have no default= parameter, unlike Python's.
Source
Thrown at src/main/java/net/starlark/java/eval/MethodLibrary.java:141
if (keyFn.isPresent()) {
try {
return stream(items)
.map(value -> ValueWithComparisonKey.make(value, keyFn.get(), thread))
.max(comparing(ValueWithComparisonKey::getComparisonKey, maxOrdering))
.get()
.getValue();
} catch (ValueWithComparisonKey.KeyCallException ex) {
Throwables.throwIfInstanceOf(ex.getCause(), EvalException.class);
Throwables.throwIfInstanceOf(ex.getCause(), InterruptedException.class);
throw new AssertionError("Got invalid ValueWithComparisonKey.KeyCallException", ex);
}
} else {
return maxOrdering.max(items);
}
} catch (ClassCastException ex) {
throw new EvalException(ex.getMessage()); // e.g. unsupported comparison: int <=> string
} catch (NoSuchElementException ex) {
throw new EvalException("expected at least one item", ex);
} finally {
EvalUtils.removeIterator(items);
}
}
/**
* Original value decorated with its comparison key; storing the comparison key alongside the
* value ensures that we call the comparison key computation function only once per original value
* (which is important in case the function has side effects).
*/
private static final class ValueWithComparisonKey {
private final Object value;
private final Object comparisonKey;
private ValueWithComparisonKey(Object value, Object comparisonKey) {
this.value = value;
this.comparisonKey = comparisonKey;
}View on GitHub (pinned to e6e199d060)
Solutions
- Guard the call: if len(items) > 0: m = max(items) else: <fallback>.
- Seed the iterable with a neutral element when the semantics allow it: max([0] + scores).
- Use a defaulting idiom: m = max(items) if items else None (then handle None downstream).
Example fix
# before
m = max([f for f in files if f.endswith('.cc')])
# after
cc = [f for f in files if f.endswith('.cc')]
m = max(cc) if cc else None Defensive patterns
Strategy: validation
Validate before calling
if len(items) == 0:
fail("cannot take max of empty list")
m = max(items) Prevention
- Check emptiness before every min()/max() on filtered data.
- Remember Starlark min/max have no default= parameter.
- Use `max(items) if items else None` as the standard idiom.
When it happens
Trigger: max([]), min(()) , max(dict()), or min/max over a comprehension/list that is empty at runtime (e.g. max([f for f in files if f.endswith('.cc')]) when no file matches).
Common situations: Glob or filter results that legitimately come back empty (no matching targets, no test files); optional attributes that default to an empty list; first iteration over generated input where the first batch is empty.
Related errors
- unsupported comparison: %s <=> %s
- invalid base %d (want 2 <= base <= 36)
- This converter doesn't support Starlark reversal.
- '" + input + "' should be >= " + minValue
- '" + input + "' should be <= " + maxValue
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/b302fda27395ce1a.
Report an issue: GitHub.