{"record":{"id":"4b92fcdbc9861e7a","repo":"bazelbuild/bazel","slug":"unsupported-comparison-s-s","errorCode":null,"errorMessage":"unsupported comparison: %s <=> %s","messagePattern":"unsupported comparison: (.+?) <=> (.+?)","errorType":"exception","errorClass":"EvalException","httpStatus":null,"severity":"error","filePath":"src/main/java/net/starlark/java/eval/EvalUtils.java","lineNumber":408,"sourceCode":"      }\n    }\n    if (y instanceof HasBinary) {\n      Object z = ((HasBinary) y).binaryOp(op, x, false);\n      if (z != null) {\n        return z;\n      }\n    }\n\n    throw Starlark.errorf(\n        \"unsupported binary operation: %s %s %s\", Starlark.type(x), op, Starlark.type(y));\n  }\n\n  // Defines the behavior of the language's ordered comparison operators (< <= => >).\n  private static int compare(Object x, Object y) throws EvalException {\n    try {\n      return Starlark.compareUnchecked(x, y);\n    } catch (ClassCastException ex) {\n      throw new EvalException(ex.getMessage());\n    }\n  }\n\n  private static String repeatString(String s, StarlarkInt in) throws EvalException {\n    int n = in.toInt(\"repeat\");\n    if (n <= 0) {\n      return \"\";\n    } else if ((long) s.length() * (long) n > Integer.MAX_VALUE) {\n      // Would exceed max length of a java String.\n      throw Starlark.errorf(\"excessive repeat (%d * %d characters)\", s.length(), n);\n    } else {\n      return s.repeat(n);\n    }\n  }\n\n  /** Evaluates a unary operation. */\n  static Object unaryOp(TokenKind op, Object x) throws EvalException {\n    switch (op) {","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/bazelbuild/bazel/blob/e6e199d0601a244511b4cf18c8b2828aa73db1fd/src/main/java/net/starlark/java/eval/EvalUtils.java#L390-L426","documentation":"Thrown when a Starlark ordered comparison operator (<, <=, >, >=) is applied to two values whose types cannot be ordered against each other. EvalUtils.compare catches the ClassCastException raised by Starlark.compareUnchecked and rethrows it as an EvalException, so the user sees 'unsupported comparison: T1 <=> T2'. Only same-type ordered values (and int/float mixtures) are comparable in Starlark.","triggerScenarios":"Evaluating 1 < \"a\", [1,2] < (1,2), None < 1, or any < between values of different Starlark types where neither side is an int/float pair. Also fires when a user-defined Comparable Starlark value is compared against an unrelated type.","commonSituations":"Sorting or comparing heterogeneous lists (e.g. sorted([\"b\", 1])), validating input where a string arrives where an int was expected, comparing depsets/tuples/lists across types, or comparing None to a number as a 'is it unset' idiom borrowed from other languages.","solutions":["Ensure both operands have the same type before comparing; convert explicitly (str(x) < str(y), int(x) < int(y)).","If comparing containers, compare element-wise or via a key function that yields a uniform type (e.g. sorted(items, key=str)).","For 'unset' checks, test identity/emptiness (x == None, if not x) instead of ordering against None.","Catch EvalException at the Java call site and surface a domain-specific message."],"exampleFix":"# before\nif version < 2:  # version is \"1.2.3\"\n    ...\n\n# after\nif int(version.split(\".\")[0]) < 2:\n    ...","handlingStrategy":"validation","validationCode":"# before comparing, ensure both sides are the same type\ndef safe_lt(x, y):\n    if type(x) != type(y) and not ((type(x) == \"int\" and type(y) == \"float\") or (type(x) == \"float\" and type(y) == \"int\")):\n        fail(\"cannot compare %s with %s\" % (type(x), type(y)))\n    return x < y","typeGuard":"def is_comparable_pair(x, y):\n    t = (type(x), type(y))\n    return t[0] == t[1] or set(t) == {\"int\", \"float\"}","tryCatchPattern":null,"preventionTips":["Never use < > on values whose types come from different sources; normalize first.","Prefer == / != for 'is it set' checks instead of ordering against None.","Sort heterogeneous data with an explicit key= that maps to one type."],"tags":["starlark","comparison","runtime","type-mismatch"],"backgroundTag":null,"analyzedSha":"e6e199d0601a244511b4cf18c8b2828aa73db1fd","analyzedAt":"2026-08-14T10:24:27.848Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}