jax-ml/jax · error · TypeError
No attribute handler defined for type: {type(val)}
Error message
No attribute handler defined for type: {type(val)} What it means
The attribute counterpart of constant lowering: when a value must become an MLIR attribute (e.g. for operation attributes during custom lowering rules), JAX looks up a registered attribute handler. If none exists for the type and the object has no __jax_array__, it raises this TypeError.
Source
Thrown at jax/_src/interpreters/mlir.py:491
return ir.ArrayAttr.get([ir_attribute(v) for v in val])
register_attribute_handler(list, _sequence_attribute_handler)
register_attribute_handler(tuple, _sequence_attribute_handler)
register_attribute_handler(ir.Attribute, lambda x: x)
register_attribute_handler(ir.Type, lambda x: x)
def ir_attribute(val: Any) -> ir.Attribute:
"""Convert a Python value to an MLIR attribute."""
for t in type(val).__mro__:
handler = _attribute_handlers.get(t)
if handler:
out = handler(val)
assert isinstance(out, ir.Attribute), (type(val), out)
return out
m = getattr(val, '__jax_array__', None)
if m is not None:
return ir_attribute(m())
raise TypeError(f"No attribute handler defined for type: {type(val)}")
# Source locations
def get_canonical_source_file(file_name: str, caches: TracebackCaches) -> str:
canonical_file_name = caches.canonical_name_cache.get(file_name, None)
if canonical_file_name is not None:
return canonical_file_name
pattern = config.hlo_source_file_canonicalization_regex.value
if pattern:
file_name = re.sub(pattern, '', file_name)
caches.canonical_name_cache[file_name] = file_name
return file_name
class HasTracebackCaches(Protocol):
@property
def traceback_caches(self) -> TracebackCaches:View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Convert the value to a numpy/JAX array or a supported scalar before it reaches ir_attribute
- Implement __jax_array__ on your class
- Register an attribute handler for your type (mirroring register_constant_handler)
- If you are a user (not a lowering author), check for accidentally passing custom objects into jitted code paths that feed attributes
Example fix
# before ctx.ir_attribute(my_obj) # TypeError: No attribute handler # after ctx.ir_attribute(np.asarray(my_obj.value))
Defensive patterns
Strategy: validation
Validate before calling
def to_attribute_safe(v):
if hasattr(v, '__jax_array__'):
return v
if not isinstance(v, (np.ndarray, np.generic, bool, int, float, complex, tuple, list)):
return np.asarray(v)
return v Try / catch
try:
attr = mlir.ir_attribute(val)
except TypeError as e:
if 'No attribute handler' in str(e):
attr = mlir.ir_attribute(np.asarray(val))
else:
raise Prevention
- In custom lowering rules, convert objects to numpy/JAX arrays before ir_attribute
- Implement __jax_array__ on custom types used in lowering
When it happens
Trigger: Writing a custom primitive/lowering rule whose impl calls mlir.ir_attribute on an unsupported Python object; passing non-array metadata (strings handled separately, but e.g. custom enums, objects) where an array-like attribute is expected in _lowering_op or composite lowering.
Common situations: Library authors implementing custom JAX primitives (esp. with composite/custom lowering APIs); version upgrades where attribute handler registration for a type was removed or moved; passing dicts/sequences whose leaves contain unsupported types recursively.
Related errors
- Sharding rule has {len(rule.operand_mappings)} operands, but
- Unsupported scalar attribute type: {type(val)}
- NumPy arrays with zero strides are not supported as MLIR att
- Invalid compute type {c_type}. Current supported values are
- custom_call backend_config unexpected type: {backend_config}
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/dd008b0f2f49ee15.
Report an issue: GitHub.