{"record":{"id":"dd008b0f2f49ee15","repo":"jax-ml/jax","slug":"no-attribute-handler-defined-for-type-type-val","errorCode":null,"errorMessage":"No attribute handler defined for type: {type(val)}","messagePattern":"No attribute handler defined for type: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/interpreters/mlir.py","lineNumber":491,"sourceCode":"  return ir.ArrayAttr.get([ir_attribute(v) for v in val])\n\nregister_attribute_handler(list, _sequence_attribute_handler)\nregister_attribute_handler(tuple, _sequence_attribute_handler)\nregister_attribute_handler(ir.Attribute, lambda x: x)\nregister_attribute_handler(ir.Type, lambda x: x)\n\ndef ir_attribute(val: Any) -> ir.Attribute:\n  \"\"\"Convert a Python value to an MLIR attribute.\"\"\"\n  for t in type(val).__mro__:\n    handler = _attribute_handlers.get(t)\n    if handler:\n      out = handler(val)\n      assert isinstance(out, ir.Attribute), (type(val), out)\n      return out\n  m = getattr(val, '__jax_array__', None)\n  if m is not None:\n    return ir_attribute(m())\n  raise TypeError(f\"No attribute handler defined for type: {type(val)}\")\n\n# Source locations\n\ndef get_canonical_source_file(file_name: str, caches: TracebackCaches) -> str:\n  canonical_file_name = caches.canonical_name_cache.get(file_name, None)\n  if canonical_file_name is not None:\n    return canonical_file_name\n\n  pattern = config.hlo_source_file_canonicalization_regex.value\n  if pattern:\n    file_name = re.sub(pattern, '', file_name)\n  caches.canonical_name_cache[file_name] = file_name\n  return file_name\n\n\nclass HasTracebackCaches(Protocol):\n  @property\n  def traceback_caches(self) -> TracebackCaches:","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/interpreters/mlir.py#L473-L509","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nctx.ir_attribute(my_obj)  # TypeError: No attribute handler\n\n# after\nctx.ir_attribute(np.asarray(my_obj.value))","handlingStrategy":"validation","validationCode":"def to_attribute_safe(v):\n    if hasattr(v, '__jax_array__'):\n        return v\n    if not isinstance(v, (np.ndarray, np.generic, bool, int, float, complex, tuple, list)):\n        return np.asarray(v)\n    return v","typeGuard":null,"tryCatchPattern":"try:\n    attr = mlir.ir_attribute(val)\nexcept TypeError as e:\n    if 'No attribute handler' in str(e):\n        attr = mlir.ir_attribute(np.asarray(val))\n    else:\n        raise","preventionTips":["In custom lowering rules, convert objects to numpy/JAX arrays before ir_attribute","Implement __jax_array__ on custom types used in lowering"],"tags":["jax","mlir","custom-primitives","attributes"],"backgroundTag":"unsupported-type-conversion","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}