bazelbuild/bazel · error · ClassCastException
unsupported comparison: %s <=> %s
Error message
unsupported comparison: %s <=> %s
What it means
The underlying throw inside Starlark.compareUnchecked: after same-type comparison and the int/float special cases, the values are mutually unordered, so it raises ClassCastException('unsupported comparison: T1 <=> T2'). Higher-level callers translate this: EvalUtils.compare wraps it into EvalException (error 100) and MethodLibrary's min/max rethrow its getMessage() (error 101). You only see the raw ClassCastException if you call compareUnchecked or an ordering built on it directly from Java.
Source
Thrown at src/main/java/net/starlark/java/eval/Starlark.java:616
Starlark.reprForErrors(x), Starlark.reprForErrors(y)));
}
}
} else {
// different types
if (x instanceof StarlarkFloat && y instanceof StarlarkInt) {
// float < int
double xf = ((StarlarkFloat) x).toDouble();
return Double.isNaN(xf) ? +1 : -StarlarkInt.compareIntAndDouble((StarlarkInt) y, xf);
} else if (x instanceof StarlarkInt && y instanceof StarlarkFloat) {
// int < float
double yf = ((StarlarkFloat) y).toDouble();
return Double.isNaN(yf) ? -1 : StarlarkInt.compareIntAndDouble((StarlarkInt) x, yf);
}
}
throw new ClassCastException(
String.format("unsupported comparison: %s <=> %s", Starlark.type(x), Starlark.type(y)));
}
/**
* Returns true if the given values are equal. Safe to use for potentially self-referential
* Starlark data structures.
*
* @throws EvalException if x and/or y is a self-referential data structures (signaled by {@link
* Object#equals} overflowing the stack)
*/
public static boolean checkedEquals(@Nullable Object x, @Nullable Object y) throws EvalException {
if (x == null) {
return y == null;
}
try {
return x.equals(y);
} catch (StackOverflowError unused) {
throw Starlark.errorf(View on GitHub (pinned to e6e199d060)
Solutions
- In host code, call the guarded wrapper (EvalUtils.compare semantics) or catch ClassCastException and translate it to your error type.
- Sort with an explicit key/ordering restricted to one type.
- Validate/normalize types before comparing (see error 100 fixes).
Example fix
// before
int cmp = Starlark.compareUnchecked(x, y); // raw ClassCastException on mismatch
// after
int cmp;
try {
cmp = Starlark.compareUnchecked(x, y);
} catch (ClassCastException e) {
throw new IllegalArgumentException("cannot order " + Starlark.type(x), e);
} Defensive patterns
Strategy: try-catch
Try / catch
// Java host code calling compareUnchecked directly
try {
int cmp = Starlark.compareUnchecked(x, y);
} catch (ClassCastException e) {
throw new IllegalArgumentException("unsupported comparison: " + Starlark.type(x) + " <=> " + Starlark.type(y), e);
} Prevention
- Prefer the guarded EvalUtils.compare path in host code over raw compareUnchecked.
- Catch StackOverflowError-turned-ClassCastException too if data may be cyclic (same exception channel).
- Restrict custom orderings to values of one known type.
When it happens
Trigger: Calling Starlark.compareUnchecked from Java embedding code (e.g. custom StarlarkCallable implementations or orderings) with e.g. a String and an Integer; using Guava Ordering.arbitrary()/natural() on mixed Starlark values outside MethodLibrary's guarded path.
Common situations: Embedding the Starlark interpreter in a host application and reusing compareUnchecked for sorting; custom builtins that sort their arguments without catching ClassCastException.
Related errors
- unsupported comparison: %s <=> %s
- unsupported comparison: %s <=> %s
- cannot compare self-referential or overly nested data struct
- This converter doesn't support Starlark reversal.
- Invalid options syntax: %s Note: Negative target patterns ca
AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14).
Data as JSON: /api/errors/7d6646eb387c6cbe.
Report an issue: GitHub.