{"record":{"id":"b36d6756f5f79a24","repo":"jax-ml/jax","slug":"dtype-is-not-a-valid-dtype-for-jax-type-promoti","errorCode":null,"errorMessage":"{dtype=} is not a valid dtype for JAX type promotion.","messagePattern":"(.+?) is not a valid dtype for JAX type promotion\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/dtypes.py","lineNumber":830,"sourceCode":"  # Note a potential algorithmic shortcut: from the definition of CUB(N), we have\n  #   ∀ c ∈ N: CUB(N) ⊆ UB(c)\n  # So if N ∩ CUB(N) is nonempty, if follows that LUB(N) = N ∩ CUB(N).\n  N = set(nodes)\n  if jax_numpy_dtype_promotion == config.NumpyDtypePromotion.STRICT:\n    UB = _strict_lattice_ubs\n  elif jax_numpy_dtype_promotion == config.NumpyDtypePromotion.STANDARD:\n    if x64:\n      UB = _standard_x64_lattice_ubs\n    else:\n      UB = _standard_x32_lattice_ubs\n  else:\n    raise ValueError(\n      f\"Unexpected value of jax_numpy_dtype_promotion={jax_numpy_dtype_promotion!r}\")\n  try:\n    bounds = [UB[n] for n in N]\n  except KeyError:\n    dtype = next(n for n in N if n not in UB)\n    raise ValueError(f\"{dtype=} is not a valid dtype for JAX type promotion.\")\n  CUB = set.intersection(*bounds)\n  LUB = (CUB & N) or {c for c in CUB if CUB.issubset(UB[c])}\n  if len(LUB) == 1:\n    return LUB.pop()\n  elif len(LUB) == 0:\n    if config.numpy_dtype_promotion.value == config.NumpyDtypePromotion.STRICT:\n      msg = (\n        f\"Input dtypes {tuple(str(n) for n in nodes)} have no available implicit dtype \"\n        \"promotion path when jax_numpy_dtype_promotion=strict. Try explicitly casting \"\n        \"inputs to the desired output type, or set jax_numpy_dtype_promotion=standard.\")\n    elif any(n in _float8_dtypes for n in nodes):\n      msg = (\n        f\"Input dtypes {tuple(str(n) for n in nodes)} have no available implicit dtype \"\n        \"promotion path. To avoid unintended promotion, 8-bit floats do not support \"\n        \"implicit promotion. If you'd like your inputs to be promoted to another type, \"\n        \"you can do so explicitly using e.g. x.astype('float32')\")\n    elif any(n in _float6_dtypes for n in nodes):\n      msg = (","sourceCodeStart":812,"sourceCodeEnd":848,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/dtypes.py#L812-L848","documentation":"JAX's type-promotion lattice only accepts a fixed set of dtypes (its node set). When computing the least upper bound of a set of dtypes, one of the inputs is not a node in the lattice — typically because it is a NumPy dtype JAX does not register, such as a non-canonical extended or unsupported dtype.","triggerScenarios":"Calling jnp.promote_types or any binary op (e.g. jnp.add) where one operand's dtype is not in the promotion lattice, e.g. np.dtype('float16') mixed with an 8-bit custom float, or a bfloat16/extended dtype combination that was never registered, or dtypes like np.float128 / numpy string dtypes reaching promotion code.","commonSituations":"Mixing exotic NumPy dtypes (float128, datetime64, str) into JAX arrays; using custom/extended dtypes in ops that go through lattice_result_type; version upgrades that changed the set of lattice nodes.","solutions":["Inspect the dtypes of all inputs (x.dtype) and cast the offending one to a supported JAX dtype: x.astype(jnp.float32)","Check that the value is not a non-numeric dtype (str/datetime/object) that leaked into an array","Report/upgrade if you are using a supported dtype combination — a missing node may be a JAX bug"],"exampleFix":"# before\nout = jnp.add(x_f16, y_custom_float8)\n\n# after\nout = jnp.add(x_f16.astype(jnp.float32), y_custom_float8.astype(jnp.float32))","handlingStrategy":"validation","validationCode":"import jax.numpy as jnp, numpy as np\nSUPPORTED = {np.dtype(d) for d in ['bool','uint8','uint16','uint32','uint64','int8','int16','int32','int64','float16','float32','float64','bfloat16','complex64','complex128']}\nassert all(np.dtype(a.dtype) in SUPPORTED for a in arrays), 'unsupported dtype in promotion'","typeGuard":null,"tryCatchPattern":"try:\n    result_type = jnp.promote_types(a.dtype, b.dtype)\nexcept ValueError:\n    result_type = jnp.float32\n    a, b = a.astype(result_type), b.astype(result_type)","preventionTips":["Cast inputs to a common canonical dtype before arithmetic","Log dtypes at data-ingestion boundaries to catch exotic NumPy dtypes early"],"tags":["jax","type-promotion","dtype","lattice"],"backgroundTag":"dtype-promotion-failure","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}