{"record":{"id":"8e8cebdaaf0c3cb7","repo":"jax-ml/jax","slug":"expected-list-got-s","errorCode":null,"errorMessage":"Expected list, got %s.","messagePattern":"Expected list, got (.+?)\\.","errorType":"validation","errorClass":"std::invalid_argument","httpStatus":null,"severity":"error","filePath":"jaxlib/pytree.cc","lineNumber":1020,"sourceCode":"          throw std::invalid_argument(\n              absl::StrFormat(\"Expected tuple, got %s.\",\n                              nb::cast<std::string_view>(nb::repr(object))));\n        }\n        nb::tuple tuple = nb::borrow<nb::tuple>(object);\n        if (tuple.size() != node.arity) {\n          throw std::invalid_argument(absl::StrFormat(\n              \"Tuple arity mismatch: %d != %d; tuple: %s.\", tuple.size(),\n              node.arity, nb::cast<std::string_view>(nb::repr(object))));\n        }\n        for (nb::handle entry : tuple) {\n          agenda.push_back(nb::borrow<nb::object>(entry));\n        }\n        break;\n      }\n\n      case PyTreeKind::kList: {\n        if (!PyList_CheckExact(object.ptr())) {\n          throw std::invalid_argument(\n              absl::StrFormat(\"Expected list, got %s.\",\n                              nb::cast<std::string_view>(nb::repr(object))));\n        }\n        nb::list list = nb::borrow<nb::list>(object);\n        if (list.size() != node.arity) {\n          throw std::invalid_argument(absl::StrFormat(\n              \"List arity mismatch: %d != %d; list: %s.\", list.size(),\n              node.arity, nb::cast<std::string_view>(nb::repr(object))));\n        }\n        for (nb::handle entry : list) {\n          agenda.push_back(nb::borrow<nb::object>(entry));\n        }\n        break;\n      }\n\n      case PyTreeKind::kDict: {\n        if (!PyDict_CheckExact(object.ptr())) {\n          throw std::invalid_argument(","sourceCodeStart":1002,"sourceCodeEnd":1038,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jaxlib/pytree.cc#L1002-L1038","documentation":"JAX's PyTreeDef::FlattenUpTo found a kList node in the stored treedef, but the object at that position is not an exact built-in list (PyList_CheckExact). List subclasses and other sequences (tuples, arrays) are rejected because the treedef records exact types for container nodes.","triggerScenarios":"Flattening against a prefix treedef where the node is a list but the runtime value is a tuple, numpy array, or a list subclass; commonly from jit cache reuse, tree structure replay, or converting containers between list and tuple during refactors.","commonSituations":"Converting list to tuple for hashing/immutability (e.g. caching keys) while the treedef still expects list, passing numpy arrays or generators where lists were traced, list subclasses from third-party libs (e.g. DataFrame rows-like subclasses).","solutions":["Pass an exact list at that position: list(x).","Regenerate the treedef from the current object instead of reusing one captured before the container-type change.","Avoid converting containers between list/tuple between tracing and calling; keep one canonical type.","Use type-stable construction helpers (always list comprehensions, not conditional tuple/list)."],"exampleFix":"# before\nobj = ((1, 2), (3, 4))            # inner was list in treedef\n# after\nobj = ([1, 2], [3, 4])            # exact lists","handlingStrategy":"type-guard","validationCode":"assert all(type(x) is list for x in my_lists), 'inner containers must be exact lists'","typeGuard":"def is_exact_list_tree(obj, ref) -> bool:\n    return jax.tree_util.tree_structure(obj).equals(\n        jax.tree_util.tree_structure(ref)\n    ) and all(type(l) is list for l in [obj] if isinstance(l, list))","tryCatchPattern":"try:\n    treedef.flatten_up_to(obj)\nexcept (ValueError, TypeError) as e:\n    if 'Expected list' in str(e):\n        obj = jax.tree_util.tree_map(lambda x: list(x) if type(x) is tuple else x, obj)\n    else:\n        raise","preventionTips":["Never silently convert list<->tuple for caching between tracing and calling.","Standardize on one sequence type per data schema; document it.","Diff tree structures in CI: assert tree_structure(new) == tree_structure(golden)."],"tags":["jax","pytree","type-mismatch","list"],"backgroundTag":"pytree-structure-mismatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}