{"record":{"id":"1de828679ec1b065","repo":"bazelbuild/bazel","slug":"cannot-compare-self-referential-or-overly-nested-d","errorCode":null,"errorMessage":"cannot compare self-referential or overly nested data structures %s and %s","messagePattern":"cannot compare self-referential or overly nested data structures (.+?) and (.+?)","errorType":"exception","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"src/main/java/net/starlark/java/eval/Starlark.java","lineNumber":595,"sourceCode":"\n  /**\n   * Defines the strict weak ordering of Starlark values used for sorting and the comparison\n   * operators.\n   *\n   * @throws ClassCastException on failure.\n   */\n  static int compareUnchecked(Object x, Object y) {\n    if (sameType(x, y)) {\n      // Ordered? e.g. string, int, bool, float.\n      if (x instanceof Comparable) {\n        @SuppressWarnings(\"unchecked\")\n        Comparable<Object> xcomp = (Comparable<Object>) x;\n        try {\n          return xcomp.compareTo(y);\n        } catch (StackOverflowError unused) {\n          // Wart: this particular error has nothing to do with class mismatch - but alas,\n          // Comparable interface uses ClassCastException for reporting all cannot-compare errors.\n          throw new ClassCastException(\n              String.format(\n                  \"cannot compare self-referential or overly nested data structures %s and %s\",\n                  Starlark.reprForErrors(x), Starlark.reprForErrors(y)));\n        }\n      }\n\n    } else {\n      // different types\n\n      if (x instanceof StarlarkFloat && y instanceof StarlarkInt) {\n        // float < int\n        double xf = ((StarlarkFloat) x).toDouble();\n        return Double.isNaN(xf) ? +1 : -StarlarkInt.compareIntAndDouble((StarlarkInt) y, xf);\n      } else if (x instanceof StarlarkInt && y instanceof StarlarkFloat) {\n        // int < float\n        double yf = ((StarlarkFloat) y).toDouble();\n        return Double.isNaN(yf) ? -1 : StarlarkInt.compareIntAndDouble((StarlarkInt) x, yf);\n      }","sourceCodeStart":577,"sourceCodeEnd":613,"githubUrl":"https://github.com/bazelbuild/bazel/blob/e6e199d0601a244511b4cf18c8b2828aa73db1fd/src/main/java/net/starlark/java/eval/Starlark.java#L577-L613","documentation":"Starlark.compareUnchecked compares same-type Comparable values by calling compareTo; a self-referential structure (a list containing itself) or one nested deeply enough makes the recursive comparison overflow the Java stack. The StackOverflowError is caught and converted to a ClassCastException with this message (a documented wart: ClassCastException is the channel for all cannot-compare errors), which callers like EvalUtils.compare then turn into an EvalException.","triggerScenarios":"x = []; x.append(x); x < x, comparing two mutually-referencing lists, or sorting a list whose elements are deeply nested structures (thousands of levels) with < or sorted().","commonSituations":"Building cyclic configuration graphs in Starlark (node lists containing node lists) and then sorting or min/max-ing them; deep AST-like data compared directly instead of by a structural key.","solutions":["Compare by a derived scalar key instead of the whole structure: sorted(nodes, key=lambda n: n.id).","Break cycles: never insert a container into itself; store indices/labels instead of direct references.","If cycles are required, compare along an explicit field path rather than recursively."],"exampleFix":"# before\nx = []\nx.append(x)\nsorted([x, []])  # recursive compare -> stack overflow\n\n# after\nx = []\nx.append(\"self\")\nsorted([x, []], key=len)","handlingStrategy":"validation","validationCode":"# never compare containers that may be cyclic; compare a derived key\nkey = lambda n: n.id  # scalar key, safe under recursion\nm = max(nodes, key=key)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store labels/indices instead of direct container references in structures you will sort.","Always sort complex values with an explicit scalar key=, never on the raw value.","Assert acyclicity when constructing nested data."],"tags":["starlark","comparison","recursion","stack-overflow","cyclic-data"],"backgroundTag":null,"analyzedSha":"e6e199d0601a244511b4cf18c8b2828aa73db1fd","analyzedAt":"2026-08-14T10:24:27.848Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}