jax-ml/jax · error · ValueError

Cannot convert_element_type from {dtype_to_string(x.dtype)}

Error message

Cannot convert_element_type from {dtype_to_string(x.dtype)} to {dtype_to_string(edtype)}

What it means

When converting an array to an extended dtype, the dtype's rules must allow the conversion (via a convert_to callback or an allow_conversion flag). If the source dtype is not an allowed input for that extended dtype (e.g. converting int32 directly to a float8 type that only accepts its representation dtype), ValueError is raised.

Source

Thrown at jax/_src/lax/lax.py:5503

  return trace.stage_value(args[0])

stage_p.def_bind_with_trace(_stage_bind_with_trace)


def _to_edtype_abstract_eval(x, *, edtype):
  assert (isinstance(edtype, dtypes.ExtendedDType) and
          not isinstance(x.dtype, dtypes.ExtendedDType))
  # For backward compatibility, if the edtype rules have a `convert_to` method,
  # use that rather than looking for an `allow_conversion: bool` attribute.
  if not isinstance(x, ShapedArray):
    raise TypeError("can only convert to an extended dtype on an array type,"
                    f"but got {type(x)}")
  if convert_to := getattr(edtype._rules, 'convert_to', None):
    allow_conversion = convert_to(x.dtype, edtype)
  else:
    allow_conversion = edtype._rules.allow_conversion
  if not allow_conversion:
    raise ValueError(
        f"Cannot convert_element_type from {dtype_to_string(x.dtype)} "
        f"to {dtype_to_string(edtype)}")
  rep_aval = core.physical_element_aval(edtype)
  assert tuple(rep_aval.sharding.spec) == (None,) * rep_aval.ndim
  if x.dtype != rep_aval.dtype:
    raise ValueError(
        "can only convert to extended dtype from its representation dtype, "
        f"but tried to convert from {dtype_to_string(x.dtype)} to "
        f"{dtype_to_string(edtype)} which doesn't match the representation type "
        f"{dtype_to_string(rep_aval.dtype)}.")
  if x.ndim < rep_aval.ndim:
    raise ValueError(
        "can only convert to extended dtype from an array of its "
        f"representation type, but the extended dtype {dtype_to_string(edtype)}"
        f" has a representation shape {rep_aval.shape} (rank {rep_aval.ndim}) "
        f"while the given representation array has shape {x.shape} (rank "
        f"{x.ndim} < {rep_aval.ndim}).")
  n = x.ndim - rep_aval.ndim

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Convert to the extended dtype's representation dtype first (e.g. jnp.float32), then to the extended dtype
  2. Check edtype._rules.allow_conversion / convert_to to see which pairs are permitted
  3. Use the documented supported source dtype for the target extended dtype
  4. For custom dtypes, extend convert_to to accept the pair if semantically valid

Example fix

// before
x_f8 = x.astype(dtypes.float8_e4m3fn)  # from int32, disallowed

// after
x_f8 = x.astype(jnp.float32).astype(dtypes.float8_e4m3fn)
Defensive patterns

Strategy: validation

Validate before calling

def conversion_allowed(src_dtype, edtype):
    fn = getattr(edtype._rules, 'convert_to', None)
    return fn(src_dtype, edtype) if fn else edtype._rules.allow_conversion

Try / catch

try:
    x_ed = x.astype(edtype)
except ValueError:
    x_ed = x.astype(jnp.float32).astype(edtype)

Prevention

When it happens

Trigger: jax.lax.convert_element_type(x, some_extended_dtype) where x.dtype is not accepted, e.g. int -> float8_e4m3fn without going through the representation dtype, or a custom extended dtype whose rules disallow the pair.

Common situations: Assuming astype(float8) works from any numeric type; custom extended dtypes with restrictive allow_conversion; version changes in ml_dtypes rules.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/e8aedf1a2411e567. Report an issue: GitHub.