{"record":{"id":"be2c879275537a4f","repo":"jax-ml/jax","slug":"can-only-convert-from-extended-dtype-to-its-repres","errorCode":null,"errorMessage":"can only convert from extended dtype to its representation dtype, but tried to convert from {dtype_to_string(x.dtype)} to {dtype_to_string(dtype)} which doesn't match the representation type {dtype_to_string(rep_aval.dtype)}.","messagePattern":"can only convert from extended dtype to its representation dtype, but tried to convert from (.+?) to (.+?) which doesn't match the representation type (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/lax.py","lineNumber":5572,"sourceCode":"\ndef _from_edtype_abstract_eval(x, *, dtype):\n  assert (isinstance(x.dtype, dtypes.ExtendedDType) and\n          not isinstance(dtype, dtypes.ExtendedDType))\n  if not isinstance(x, ShapedArray):\n    raise TypeError(\"can only convert from an extended dtype on an array type,\"\n                    f\"but got {type(x)}\")\n  if convert_from := getattr(x.dtype._rules, 'convert_from', None):\n    allow_conversion = convert_from(x.dtype, dtype)\n  else:\n    allow_conversion = x.dtype._rules.allow_conversion\n  if not allow_conversion:\n    raise ValueError(\n        f\"Cannot convert_element_type from {dtype_to_string(x.dtype)} \"\n        f\"to {dtype_to_string(dtype)}\")\n  rep_aval = core.physical_element_aval(x.dtype)\n  assert tuple(rep_aval.sharding.spec) == (None,) * rep_aval.ndim\n  if rep_aval.dtype != dtype:\n    raise ValueError(\n        \"can only convert from extended dtype to its representation dtype, \"\n        f\"but tried to convert from {dtype_to_string(x.dtype)} to \"\n        f\"{dtype_to_string(dtype)} which doesn't match the representation type \"\n        f\"{dtype_to_string(rep_aval.dtype)}.\")\n  if isinstance(x, ShapedArray):\n    return x.update(shape=(*x.shape, *rep_aval.shape), dtype=dtype)\n  else:\n    assert False  # unreachable, see isinstance check above\n\nfrom_edtype_p = Primitive('from_edtype')\nfrom_edtype_p.def_impl(partial(dispatch.apply_primitive, from_edtype_p))\nfrom_edtype_p.def_abstract_eval(_from_edtype_abstract_eval)\nad.defjvp(from_edtype_p,\n          lambda t, x, dtype:\n          convert_element_type(t, core.primal_dtype_to_tangent_dtype(dtype)))\nad.primitive_transposes[from_edtype_p] = \\\n    lambda ct, x, dtype: [to_edtype_p.bind(ct, edtype=x.dtype)]\nbatching.defvectorized(from_edtype_p)","sourceCodeStart":5554,"sourceCodeEnd":5590,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/lax.py#L5554-L5590","documentation":"After rule-level approval, converting from an extended dtype requires the target dtype to exactly equal the extended dtype's representation dtype (e.g. uint8). If the requested dtype differs from the physical storage type, ValueError is raised with both dtypes and the required representation type.","triggerScenarios":"convert_element_type(x_ed, dtype) with dtype != physical_element_aval(x_ed.dtype).dtype, e.g. reading a uint8-represented dtype out as int8 or float32.","commonSituations":"Signedness mixups (int8 vs uint8 representation); assuming the logical type (float8) can be materialized directly as float32; changing representation assumptions across versions of a custom dtype.","solutions":["Use exactly the representation dtype: query it with jax.core.physical_element_aval(x.dtype).dtype","Then cast the result to the final desired dtype in a second step","Double-check uint vs int signedness of the representation","For numeric semantics, convert via the allowed path (edtype -> rep dtype -> float) per the rules"],"exampleFix":"// before\ny = x_ed.astype(jnp.int8)  # representation is uint8\n\n// after\ny = x_ed.astype(jnp.uint8).astype(jnp.int8)","handlingStrategy":"validation","validationCode":"from jax.core import physical_element_aval\nrep = physical_element_aval(x.dtype).dtype\nif target != rep:\n    plan = (rep, target)  # two-step conversion","typeGuard":null,"tryCatchPattern":"try:\n    y = lax.convert_element_type(x_ed, target)\nexcept ValueError:\n    y = lax.convert_element_type(x_ed, rep_of(x_ed)).astype(target)","preventionTips":["Cache physical_element_aval(...).dtype per extended dtype","Check signedness (uint8 vs int8) of representation types","Write helper convert_from_ed(x, target) that does the two-step cast"],"tags":["jax","extended-dtype","dtype-conversion","representation"],"backgroundTag":"disallowed-dtype-conversion","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}