{"record":{"id":"8bb9639985e3797c","repo":"jax-ml/jax","slug":"value-of-type-type-self-is-not-compatible-with","errorCode":null,"errorMessage":"Value of type {type(self)} is not compatible with the Array API.","messagePattern":"Value of type (.+?) is not compatible with the Array API\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/core.py","lineNumber":1168,"sourceCode":"      raise TypeError(f\"Value of type {type(self)} is not convertible to integer index.\")\n    return self.aval._index(self)\n\n  # raises a useful error on attempts to pickle a Tracer.\n  def __reduce__(self):\n    raise ConcretizationTypeError(\n      self, (\"The error occurred in the __reduce__ method, which may \"\n             \"indicate an attempt to serialize/pickle a traced value.\"))\n\n  # raises the better error message from ShapedArray\n  def __setitem__(self, key, value):\n    if not hasattr(self.aval, \"_setitem\"):\n      raise TypeError(f\"Value of type {type(self)} is not indexable.\")\n    return self.aval._setitem(self, key, value)\n\n  # NumPy also only looks up special methods on classes.\n  def __array_module__(self, types):\n    if not hasattr(self.aval, \"_array_module\"):\n      raise TypeError(f\"Value of type {type(self)} is not compatible with the Array API.\")\n    return self.aval._array_module(self, types)\n\n  def __getattr__(self, name):\n    # if the aval property raises an AttributeError, gets caught here\n    assert not config.enable_checks.value or name != \"aval\"\n\n    # These must raise AttributeError in the base class for backward compatibility.\n    # TODO(jakevdp): can we change this and make them raise NotImplementedError instead?\n    if name in [\"block_until_ready\", \"copy_to_host_async\"]:\n      raise AttributeError(\n        f\"The '{name}' method is not available on {self._error_repr()}.\"\n        f\"{self._origin_msg()}\")\n\n    if name == 'sharding':\n      raise AttributeError(\n        f\"The 'sharding' attribute is not available on {self._error_repr()}. \"\n        \"To query sharding information on tracers, use `jax.typeof(x)`.\")\n","sourceCodeStart":1150,"sourceCodeEnd":1186,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/core.py#L1150-L1186","documentation":"Raised by JaxTracer.__array_module__ when a library using the Python array API standard protocol asks a Tracer for its array module (via __array_module__(types)) and the tracer's aval does not implement _array_module. This protocol is how NumPy>=1.22 and array-api-compatible libraries decide whether they can dispatch NEP-35 style operations on an object; tracers cannot participate, so JAX refuses.","triggerScenarios":"Calling np.ndarray.__array_module__ dispatch paths on a tracer, e.g. numpy_function(jax_tracer) where NumPy inspects the object via the array module protocol; using array-api-compat or libraries like scipy that probe __array_module__; np.asarray-like coercion inside jit/grad where the tracer is passed to host code.","commonSituations":"Passing traced JAX values to NumPy/SciPy functions that don't understand NEP-35 dispatch; calling pandas/sklearn utilities on values captured inside a jitted function; version upgrades where NumPy started preferring __array_module__ over __array__ for protocol negotiation.","solutions":["Replace the NumPy/SciPy call with its jax.numpy / jax.scipy equivalent inside the traced function.","If the operation cannot run under tracing, hoist it out: return the value from jit, do the NumPy work on the concrete host array, then re-enter JAX.","Mark genuinely static arguments via static_argnums/static_argnames so they arrive as normal arrays/objects.","For third-party numerics, check if the library supports JAX via the array API or a jax backend parameter."],"exampleFix":"# before\n@jax.jit\ndef f(x):\n    return np.sqrt(x) + scipy.special.gammaln(x)  # probes __array_module__\n\n# after\nimport jax.numpy as jnp\nimport jax.scipy as jsp\n@jax.jit\ndef f(x):\n    return jnp.sqrt(x) + jsp.special.gammaln(x)","handlingStrategy":"type-guard","validationCode":"import jax\ndef is_tracer(x) -> bool:\n    return isinstance(x, jax.core.Tracer)\n# route dispatch before calling numpy code\ndef dispatch(x):\n    return (jax.numpy if is_tracer(x) else __import__('numpy'))","typeGuard":"import jax\ndef is_tracer(x) -> bool:\n    return isinstance(x, jax.core.Tracer)","tryCatchPattern":null,"preventionTips":["Inside jit/grad use jax.numpy and jax.scipy exclusively, never numpy/scipy direct calls.","Hoist non-JAX numerics outside the traced region and pass concrete arrays across the boundary.","Mark truly static array arguments with static_argnames.","Pin NumPy>=1.22 behavior expectations and test wrapped functions with tracers in unit tests."],"tags":["jax","tracer","numpy-interop","array-api","nep-35"],"backgroundTag":"numpy-duck-typing-dispatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}