jax-ml/jax · error · TypeError

Value of type {type(self)} is not convertible to hex.

Error message

Value of type {type(self)} is not convertible to hex.

What it means

Raised by JAXTracer.__hex__ when hex() is called on a JAX Tracer whose aval does not implement _hex — i.e. on a symbolic value being traced by a JAX transformation. hex() requires a concrete integer on the host, which tracers do not have. JAX blocks it with a clear TypeError instead of failing obscurely later.

Source

Thrown at jax/_src/core.py:1136

    return self.aval._int(self)

  def __float__(self):
    check_scalar_conversion(self)
    if not hasattr(self.aval, "_float"):
      raise TypeError(f"Value of type {type(self)} is not convertible to float.")
    return self.aval._float(self)

  def __complex__(self):
    check_scalar_conversion(self)
    if not hasattr(self.aval, "_complex"):
      raise TypeError(f"Value of type {type(self)} is not convertible to complex.")
    return self.aval._complex(self)

  def __hex__(self):
    if is_concrete(self): return hex(self.to_concrete_value())
    check_integer_conversion(self)
    if not hasattr(self.aval, "_hex"):
      raise TypeError(f"Value of type {type(self)} is not convertible to hex.")
    return self.aval._hex(self)

  def __oct__(self):
    if is_concrete(self): return oct(self.to_concrete_value())
    check_integer_conversion(self)
    if not hasattr(self.aval, "_oct"):
      raise TypeError(f"Value of type {type(self)} is not convertible to oct.")
    return self.aval._oct(self)

  def __index__(self):
    if is_concrete(self): return operator.index(self.to_concrete_value())
    check_integer_conversion(self)
    if not hasattr(self.aval, "_index"):
      raise TypeError(f"Value of type {type(self)} is not convertible to integer index.")
    return self.aval._index(self)

  # raises a useful error on attempts to pickle a Tracer.
  def __reduce__(self):

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Remove hex() calls from traced code; use jax.debug.print with integer formatting to inspect values.
  2. Return the traced integer from the function and hex() the concrete result on the host after the transformation completes.
  3. If hex output of bits is required inside the trace, compute it symbolically with jax.numpy operations instead of the Python builtin.

Example fix

# before
@jax.jit
def f(i):
    print(hex(i))   # TypeError
    return i + 1

# after
@jax.jit
def f(i):
    jax.debug.print('i={i}', i=i)
    return i + 1
Defensive patterns

Strategy: validation

Validate before calling

import jax
def describe_int(x) -> str:
    if isinstance(x, jax.core.Tracer):
        raise ValueError('cannot hex-format a tracer; inspect after transform returns')
    return hex(int(x))

Type guard

import jax
def is_concrete_int(x) -> bool:
    return not isinstance(x, jax.core.Tracer) and isinstance(int(x), int)

Try / catch

try:
    s = hex(x)
except TypeError as e:
    if 'not convertible' in str(e):
        jax.debug.print('x={x}', x=x); s = '<tracer>'
    else:
        raise

Prevention

When it happens

Trigger: Calling hex(tracer) inside code traced by jax.jit/grad/vmap/scan; formatting traced integer values with f'{x:#x}' or '%#x' % x (which routes through __format__/__hex__ paths); debugging prints of traced indices or counters.

Common situations: Debug-printing loop counters or indices from jax.lax.fori_loop/scan with hex formatting; porting bit-manipulation or hashing code that hex-dumps intermediate values; logging inside jitted functions.

Related errors


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