{"record":{"id":"c4ec842096be1387","repo":"jax-ml/jax","slug":"a-shapedtypestruct-does-not-have-a-value-and-canno","errorCode":null,"errorMessage":"A ShapeDtypeStruct does not have a value and cannot be used as a constant in a JAX function.","messagePattern":"A ShapeDtypeStruct does not have a value and cannot be used as a constant in a JAX function\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/interpreters/mlir.py","lineNumber":341,"sourceCode":"      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)\n\ndef _ndarray_constant_handler(val: np.ndarray | np.generic,\n                              aval: core.AbstractValue | None) -> IrValues:\n  \"\"\"Constant handler for ndarray literals, handling zero-size strides.\n\n  In most cases this function calls _numpy_array_constant(val) except it has\n  special handling of arrays with any strides of size zero: for those, it\n  generates appropriate calls to NumpyArrayConstant, Broadcast, and Transpose\n  to avoid staging in large literals that might arise from np.zeros or np.ones\n  or the output of lax.broadcast (which uses np.broadcast_to which in turn\n  uses size-zero strides).\n\n  Args:\n    val: an ndarray.","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/interpreters/mlir.py#L323-L359","documentation":"ShapeDtypeStruct describes only a shape and dtype — it carries no data — so it cannot be materialized as a constant in an MLIR computation. JAX registers a handler that always raises to catch attempts to use these placeholder objects where actual values are required.","triggerScenarios":"Passing a jax.ShapeDtypeStruct (e.g. from jax.eval_shape, shard_map args, or checkify/pjit specs) as a value argument to a jitted function instead of using it to describe metadata; feeding aval-shaped placeholders into computations that get traced as constants.","commonSituations":"Prototyping with eval_shape outputs and then reusing the struct as data; wiring donation/partitioning specs where a struct leaks into argument position; confusing ShapeDtypeStruct with zeros(struct.shape, struct.dtype).","solutions":["Replace the struct with a real array: jnp.zeros(s.shape, s.dtype)","Use the struct only for metadata (shape/dtype) in APIs that accept it (e.g. eval_shape, pjit in_specs)","Check for accidental mixing of metadata dicts and data in argument lists"],"exampleFix":"# before\nout = jitted_fn(ShapeDtypeStruct((3,), jnp.float32))  # TypeError\n\n# after\nout = jitted_fn(jnp.zeros((3,), jnp.float32))","handlingStrategy":"type-guard","validationCode":"import jax\n\ndef ensure_array(v):\n    if isinstance(v, jax.ShapeDtypeStruct):\n        return jnp.zeros(v.shape, v.dtype)\n    return v","typeGuard":"import jax\n\ndef is_shape_dtype_struct(v) -> bool:\n    return isinstance(v, jax.ShapeDtypeStruct)","tryCatchPattern":null,"preventionTips":["Keep metadata (ShapeDtypeStruct) and data in separate variables/naming","Use eval_shape outputs only for shape inference, never as arguments"],"tags":["jax","shape-dtype-struct","constants"],"backgroundTag":"placeholder-used-as-value","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}