jax-ml/jax · error · ConcretizationTypeError

The is_deleted() method was called on {self._error_repr()}.{

Error message

The is_deleted() method was called on {self._error_repr()}.{self._origin_msg()}

What it means

ConcretizationTypeError raised when Tracer.is_deleted() is called. is_deleted() reports whether a materialized jax.Array's buffers were explicitly deleted; tracers own no buffers so the question is meaningless and the base-class stub raises ConcretizationTypeError.

Source

Thrown at jax/_src/core.py:1255

  def delete(self):
    raise ConcretizationTypeError(self,
      f"The delete() method was called on {self._error_repr()}."
      f"{self._origin_msg()}")

  def devices(self):
    raise ConcretizationTypeError(self,
      f"The devices() method was called on {self._error_repr()}."
      f"{self._origin_msg()}")

  @property
  def global_shards(self):
    raise ConcretizationTypeError(self,
      f"The global_shards property was called on {self._error_repr()}."
      f"{self._origin_msg()}")

  def is_deleted(self):
    raise ConcretizationTypeError(self,
      f"The is_deleted() method was called on {self._error_repr()}."
      f"{self._origin_msg()}")

  @property
  def is_fully_addressable(self):
    raise ConcretizationTypeError(self,
      f"The is_fully_addressable property was called on {self._error_repr()}."
      f"{self._origin_msg()}")

  @property
  def is_fully_replicated(self):
    raise ConcretizationTypeError(self,
      f"The is_fully_replicated property was called on {self._error_repr()}."
      f"{self._origin_msg()}")

  def on_device_size_in_bytes(self):
    raise ConcretizationTypeError(self,
      f"The on_device_size_in_bytes() method was called on {self._error_repr()}."

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Remove the is_deleted() check from traced code; traced intermediates cannot be deleted.
  2. Perform liveness checks on concrete arrays before/after calling the jitted function.
  3. If buffer reuse matters, use jax.jit(..., donate_argnums=...) to let JAX reclaim argument buffers safely.
  4. Guard with isinstance(x, jax.Array) if the helper must serve both traced and concrete values.

Example fix

// before
@jax.jit
def f(x):
    if x.is_deleted(): ...   # ConcretizationTypeError
    return x + 1

// after
@jax.jit
def f(x):
    return x + 1
# caller: if x.is_deleted(): x = x.copy()
Defensive patterns

Strategy: type-guard

Validate before calling

import jax

def is_deleted_safe(x) -> bool:
    if isinstance(x, jax.core.Tracer):
        return False
    return x.is_deleted()

Type guard

import jax
from jax.core import Tracer

def liveness_checkable(x) -> bool:
    return isinstance(x, jax.Array) and not isinstance(x, Tracer)

Try / catch

from jax.errors import ConcretizationTypeError
try:
    gone = x.is_deleted()
except ConcretizationTypeError:
    gone = False  # tracers are never 'deleted'

Prevention

When it happens

Trigger: Calling `x.is_deleted()` on a value being traced inside jax.jit/grad/vmap/pmap/scan/remat or a custom derivative rule.

Common situations: Defensive cleanup code that checks is_deleted() before reusing buffers, reused inside a jitted training step; buffer-pool logic written for concrete arrays getting applied to traced intermediates; refactoring data-loader code under vmap.

Related errors


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