{"record":{"id":"d1a68fc780a78455","repo":"jax-ml/jax","slug":"cannot-handle-new-consts-created-by-state-discharg","errorCode":null,"errorMessage":"Cannot handle new consts created by state discharge.","messagePattern":"Cannot handle new consts created by state discharge\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"jax/_src/pallas/primitives.py","lineNumber":768,"sourceCode":"    collective_axes,\n    ref_transforms,\n    **_,\n):\n  if collective_axes:\n    raise NotImplementedError(\n        \"run_scoped discharge does not support collective_axes yet.\"\n    )\n  # discharge_state only discharges invars, not consts, so in order to\n  # discharge the requested refs we need to move them to the invar set.\n  jaxpr_noconst = pe.convert_constvars_jaxpr(jaxpr)\n  num_return_values = len(jaxpr_noconst.outvars)\n  discharged_closed_body = state_discharge.discharge_state(\n      jaxpr_noconst,\n      should_discharge=ctx.should_discharge + [False] * len(jaxpr.invars),\n  )\n  discharged_body, new_consts = discharged_closed_body, discharged_closed_body.consts\n  if new_consts:\n    raise NotImplementedError(\n        \"Cannot handle new consts created by state discharge.\")\n\n  # Lowering expects that the jaxpr.consts to be the eqn.invals.\n  discharged_body = discharged_body.with_consts(args_flat)\n\n  # Run_scoped discharged the external variables but the scoped ones\n  # are not discharged.\n  out = run_scoped_p.bind(\n      *args_flat, jaxpr=discharged_body, collective_axes=collective_axes,\n      ref_transforms=ref_transforms,\n  )\n  # Order of outputs:\n  # (1) return values, (2) closed refs, (3) scoped refs.\n  return_values = out[:num_return_values]\n  ref_outputs = out[num_return_values:]\n  # We update all ref values with their updated values from the discharged\n  # body. For other values we leave them in place.\n  updates = [","sourceCodeStart":750,"sourceCodeEnd":786,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/pallas/primitives.py#L750-L786","documentation":"When discharging state for run_scoped, the state_discharge transformation unexpectedly produced new constants (captured values) in the discharged jaxpr, which this lowering path cannot handle. Only pre-existing invars/consts are supported.","triggerScenarios":"A run_scoped body whose discharged jaxpr closes over new constants after discharge_state runs (e.g., derived constants created during discharge of scoped refs).","commonSituations":"Complex kernels where discharge materializes new constant values; typically a JAX version-specific internal limitation rather than a user API mistake.","solutions":["Simplify the run_scoped body so discharge does not create new constants (hoist computations out of run_scoped)","Update JAX to the latest version — this is an internal discharge limitation that gets fixed over time","Report the reproducer to the JAX team if it persists on latest"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    out = run_scoped(f, refs)\nexcept NotImplementedError as e:\n    if \"new consts\" in str(e):\n        # simplify body / hoist constants and retry\n        out = run_scoped(simplified_f, refs)\n    raise","preventionTips":["Keep run_scoped bodies simple; hoist constants out","Track JAX release notes for state-discharge fixes"],"tags":["pallas","state-discharge","run-scoped","not-implemented","jax"],"backgroundTag":"unsupported-feature-not-implemented","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}