{"record":{"id":"08bea57c6a345d76","repo":"jax-ml/jax","slug":"non-bool-prevent-cse-together-with-static-argnums","errorCode":null,"errorMessage":"non-bool prevent_cse together with static_argnums/static_argnames","messagePattern":"non-bool prevent_cse together with static_argnums/static_argnames","errorType":"error_code","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"jax/_src/ad_checkpoint.py","lineNumber":1008,"sourceCode":"  custom_vjp's fwd rule* is rematerialized as an opaque unit. For the\n  conventional idiom of a fwd rule calling its own custom_vjp-decorated\n  function to compute the primal output, that is exactly the intended\n  semantics. Values and gradients are unaffected at every order of\n  differentiation. The one observable consequence arises only under\n  higher-order AD: differentiating a second time runs the inner application's\n  own fwd rule (at first order it never runs, since the outer bwd rule\n  discharges the derivative), and values inside it (e.g.\n  ``checkpoint_name``-tagged intermediates) cannot be marked saveable by the\n  checkpoint ``policy`` there; they are always recomputed.\n  \"\"\"\n  kwargs = dict(policy=policy, static_argnums=static_argnums,\n                static_argnames=static_argnames, prevent_cse=prevent_cse)\n  if f is None: return lambda g: _remat3(g, **kwargs)\n  return _remat3(f, **kwargs)\n\ndef _remat3(f, *, policy, static_argnums, static_argnames, prevent_cse=True):\n  if not isinstance(prevent_cse, bool) and (static_argnums or static_argnames):\n    raise NotImplementedError(\n        \"non-bool prevent_cse together with static_argnums/static_argnames\")\n  @wraps(f)\n  def decorator(*args, **kwargs):\n    if static_argnums or static_argnames:\n      # Like classic remat (and custom_vjp3), support unhashable static\n      # values by closing over them instead of threading them through the\n      # tracing machinery, which hashes them.\n      args_ = api_util.resolve_kwargs(f, args, kwargs)\n      argnums_ = (static_argnums,) if type(static_argnums) is int else static_argnums\n      argnums = frozenset(i % len(args_) for i in _static_argnums(\n          f, argnums_, static_argnames))\n      if not all(api_util.is_hashable(args_[i]) for i in argnums):\n        which_static = [i in argnums for i in range(len(args_))]\n        dyn_args, static_args = partition_list(which_static, args_)\n        f2 = _dyn_args_fun(f, argnums, tuple(map(WrapHashably, static_args)),\n                           len(args_))\n        return _remat3(f2, policy=policy, static_argnums=(),\n                       static_argnames=())(*dyn_args)","sourceCodeStart":990,"sourceCodeEnd":1026,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/ad_checkpoint.py#L990-L1026","documentation":"After the top-level FromIterableTreeHelper call returned, the traversal iterator is not exhausted, meaning the input had fewer nodes than the treedef: the input tree is shallower than the treedef.","triggerScenarios":"treedef.FromIterableTree(xs) with xs less nested (or smaller) than the treedef expects.","commonSituations":"Feeding scalars or flat lists where nested tuples are required; template/output-shape mismatches.","solutions":["Nest the input to match the treedef structure","Validate structure with tree_structure comparisons before calling","Use a treedef derived from the input itself"],"exampleFix":"# before\nout = treedef.from_iterable_tree([a, b])  # treedef expects ((a,b),(c,d))\n# after\nout = treedef.from_iterable_tree([(a, b), (c, d)])","handlingStrategy":"type-guard","validationCode":"def from_iterable_safe(treedef, xs):\n    try:\n        return treedef.from_iterable_tree(xs)\n    except ValueError:\n        return None\nout = from_iterable_safe(treedef, xs)\nif out is None:\n    _, treedef = jax.tree_util.tree_flatten(xs_template_correctly_nested)","typeGuard":"def shape_ok(treedef, xs) -> bool:\n    try:\n        treedef.from_iterable_tree(xs)\n        return True\n    except ValueError:\n        return False","tryCatchPattern":"try:\n    treedef.from_iterable_tree(xs)\nexcept ValueError as e:\n    if 'Tree structures did not match' in str(e):\n        xs = _add_missing_nesting(xs)\n    else:\n        raise","preventionTips":["Validate nesting depth before rebuilding","Use treedefs derived from the same data shape","Wrap from_iterable_tree in structure checks in library code"],"tags":["pytree","jax","structure-mismatch","from-iterable"],"backgroundTag":"pytree-structure-mismatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}