jax-ml/jax · error · TypeError

Cannot determine dtype of {x}

Error message

Cannot determine dtype of {x}

What it means

dtype(x) fell back to np.result_type(x) to infer the dtype of an array-like, and NumPy itself raised TypeError — meaning x has no inferable dtype (e.g. a ragged list, an arbitrary object, or a sequence of incompatible items).

Source

Thrown at jax/_src/dtypes.py:1042

  if isinstance(x, (str, np.dtype)):
    dt = np.dtype(x)
    if dt not in _jax_dtype_set and not issubdtype(dt, extended):
      raise TypeError(f"Value '{x}' with dtype {dt} is not a valid JAX array "
                      "type. Only arrays of numeric types are supported by JAX.")
    return _maybe_canonicalize_explicit_dtype(dt, "dtype")

  # If x has a dtype attribute, and it's a valid dtype, use it. This avoids
  # calling np.result_type on objects that might have a .dtype but are not
  # standard NumPy array-like, which can lead to warnings in NumPy 2.4+.
  dt_attr = getattr(x, 'dtype', None)
  if issubdtype(dt_attr, extended) or isinstance(dt_attr, np.dtype):
    dt = dt_attr
  else:
    try:
      dt = np.result_type(x)
    except TypeError as err:
      raise TypeError(f"Cannot determine dtype of {x}") from err
  if dt not in _jax_dtype_set and not issubdtype(dt, extended):
    raise TypeError(f"Value '{x}' with dtype {dt} is not a valid JAX array "
                    "type. Only arrays of numeric types are supported by JAX.")
  # TODO(jakevdp): fix return type annotation and remove this ignore.
  return canonicalize_dtype(dt, allow_extended_dtype=True)  # pyrefly: ignore[bad-return]

def lattice_result_type(*args: Any) -> tuple[DType, bool]:
  dtypes, weak_types = zip(*(_dtype_and_weaktype(arg) for arg in args))
  if len(dtypes) == 1:
    out_dtype = dtypes[0]
    out_weak_type = weak_types[0]
  elif len(set(dtypes)) == 1 and not all(weak_types):
    # Trivial promotion case. This allows extended dtypes through.
    out_dtype = dtypes[0]
    out_weak_type = False
  elif all(weak_types) and config.numpy_dtype_promotion.value != config.NumpyDtypePromotion.STRICT:
    # If all inputs are weakly typed, we compute the bound of the strongly-typed
    # counterparts and apply the weak type at the end. This avoids returning the

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Normalize the input to a proper ndarray first: np.asarray(data, dtype=np.float32)
  2. Validate/flatten nested structures (or use padding) before inferring dtypes
  3. Catch TypeError around dtype inference and produce a clear user-facing message with the offending value

Example fix

# before
dt = jax.dtypes.dtype(maybe_ragged)

# after
if isinstance(maybe_ragged, list):
    maybe_ragged = np.asarray(maybe_ragged, dtype=np.float32)
dt = jax.dtypes.dtype(maybe_ragged)
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
try:
    a = np.asarray(x)
except (TypeError, ValueError):
    a = None  # reject before calling dtype()
assert a is not None, f'cannot convert {x!r} to array'

Type guard

def is_array_like_with_dtype(x) -> bool:
    import numpy as np
    try:
        np.result_type(x)
        return True
    except TypeError:
        return False

Try / catch

try:
    dt = jax.dtypes.dtype(x)
except TypeError as e:
    raise ValueError(f'cannot infer dtype for input {x!r}') from e

Prevention

When it happens

Trigger: jax.dtypes.dtype([[1,2],[3]]) (ragged nested list), dtype(some_random_object), dtype of a list whose elements are untyped Python objects; the object had no .dtype attribute and np.result_type failed.

Common situations: Passing unstructured Python objects or ragged data into APIs that expect array-likes; user-supplied config values that are sometimes lists of mixed types; None elements inside a list ([1, None]).

Related errors


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