{"record":{"id":"75450f8a1856fa82","repo":"jax-ml/jax","slug":"no-constant-handler-for-type-type-val","errorCode":null,"errorMessage":"No constant handler for type: {type(val)}","messagePattern":"No constant handler for type: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/interpreters/mlir.py","lineNumber":327,"sourceCode":"\ndef _ir_constant(val: Any, *,\n  const_lowering: dict[tuple[int, core.AbstractValue], IrValues] | None = None,\n  aval: core.AbstractValue | None = None\n) -> IrValues:\n  if const_lowering is not None:\n    # pyrefly: ignore[bad-argument-type]\n    if np.shape(val) and (c_val := const_lowering.get((id(val), aval))) is not None:\n      return c_val\n  for t in type(val).__mro__:\n    handler = _constant_handlers.get(t)\n    if handler:\n      out = handler(val, aval)\n      assert _is_ir_values(out), (type(val), out)\n      return out\n  m = getattr(val, '__jax_array__', None)\n  if m is not None:\n    return ir_constant(m())\n  raise TypeError(f\"No constant handler for type: {type(val)}\")\n\n\ndef _numpy_array_constant(x: np.ndarray | np.generic) -> ir.Value:\n  return hlo.constant(_numpy_array_attribute(x))\n\n\ndef _masked_array_constant_handler(*args, **kwargs):\n  raise ValueError(\"numpy masked arrays are not supported as direct inputs to JAX functions. \"\n                   \"Use arr.filled() to convert the value to a standard numpy array.\")\n\nregister_constant_handler(np.ma.MaskedArray, _masked_array_constant_handler)\n\ndef _shape_dtype_struct_constant_handler(*args, **kwargs):\n  raise TypeError(\"A ShapeDtypeStruct does not have a value and cannot be \"\n                  \"used as a constant in a JAX function.\")\n\nregister_constant_handler(core.ShapeDtypeStruct,\n                          _shape_dtype_struct_constant_handler)","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/interpreters/mlir.py#L309-L345","documentation":"Raised by JAX's MLIR lowering machinery when a Python object passed as a constant to a jitted function has no registered constant handler for its type. During tracing/lowering, every concrete value must be converted into an MLIR constant; only types with registered handlers (numpy arrays/scalars, Python scalars, etc.) or objects exposing __jax_array__ can be lowered. Any other type (e.g. a custom class, torch tensor, dict, string in an unexpected path) reaches the fallback and triggers this TypeError.","triggerScenarios":"Passing an object of an unregistered type as a static/constant argument to jit/pmap/scan/pmap-style lowering, e.g. a custom Python class, a non-JAX array (torch.Tensor, pandas object), or a dict where a scalar is expected; also when a user-defined aval/ShapeDtypeStruct-like object is fed as a value.","commonSituations":"Mixing JAX with other frameworks (passing a torch tensor directly), passing custom dataclass instances into jitted code, stale registrations after upgrading JAX where a handler moved, or passing nested containers holding unsupported leaves.","solutions":["Convert the value to a numpy array or JAX array (jnp.asarray / np.asarray) before passing it","If it is a custom object, implement __jax_array__ returning a jnp array, or restructure to pass plain arrays","Move non-array configuration objects into static_argnums/static_argnames so they are treated as Python constants, not traced values","Register a constant handler with register_constant_handler if you control the type"],"exampleFix":"// before\nf = jax.jit(lambda x, cfg: x * cfg.scale)\nf(jnp.ones(3), MyConfig(scale=2))  # TypeError: No constant handler\n\n// after\nf = jax.jit(lambda x, scale: x * scale, static_argnames=('scale',))\nf(jnp.ones(3), 2)","handlingStrategy":"type-guard","validationCode":"def is_lowerable_const(v):\n    return hasattr(v, '__jax_array__') or isinstance(v, (np.ndarray, np.generic, bool, int, float, complex))\n\nargs = [a for a in args if not isinstance(a, (str, dict))]","typeGuard":"def is_jax_constant(v) -> bool:\n    return hasattr(v, '__jax_array__') or isinstance(\n        v, (np.ndarray, np.generic, bool, int, float, complex))","tryCatchPattern":"try:\n    out = jitted_fn(x)\nexcept TypeError as e:\n    if 'No constant handler' in str(e):\n        x = np.asarray(x)  # or move to static args\n        out = jitted_fn(x)\n    else:\n        raise","preventionTips":["Convert all inputs with jnp.asarray before calling jitted functions","Pass configuration objects via static_argnames, never as traced values","Never feed tensors from other frameworks directly into JAX"],"tags":["jax","constants","type-error","tracing"],"backgroundTag":"unsupported-type-conversion","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}