{"record":{"id":"51c744e952304158","repo":"jax-ml/jax","slug":"self-r-has-no-dtype","errorCode":null,"errorMessage":"{self!r} has no `dtype`.","messagePattern":"(.+?) has no `dtype`\\.","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"jax/_src/state/types.py","lineNumber":341,"sourceCode":"\n    if self.multiref:\n      ref_ty = tuple(_type(r) for r in self.ref)\n      return cast(MultiRefTransform, self.transforms[0]).transform_types(ref_ty)\n    ref_ty = _type(self.ref)\n    for t in self.transforms:\n      ref_ty = t.transform_type(ref_ty)\n    return ref_ty\n\n  @property\n  def shape(self) -> tuple[int | Array, ...]:\n    if not hasattr(self.type, \"shape\"):\n      raise AttributeError(f\"{self!r} has no `shape`.\") from None\n    return self.type.shape\n\n  @property\n  def dtype(self):\n    if not hasattr(self.type, \"dtype\"):\n      raise AttributeError(f\"{self!r} has no `dtype`.\") from None\n    return self.type.dtype\n\n  ndim = property(lambda self: len(self.shape))\n  size = property(lambda self: math.prod(self.shape))\n  T = property(lambda self: self.transpose(tuple(reversed(range(self.ndim)))))\n\n  @property\n  def at(self) -> RefIndexer:\n    return RefIndexer(self)\n\n  def bitcast(self, dtype):\n    if self.is_dynamic_size:\n      raise NotImplementedError(\n          \"Bitcast ref with dynamic size is not supported.\"\n      )\n    dtype = dtypes.dtype(dtype)\n    if self.multiref:\n      return TransformedRef(self, (BitcastTransform(dtype),))","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/state/types.py#L323-L359","documentation":"TransformedRef.dtype raises AttributeError when the transformed type has no dtype attribute. Since bitcast reads .dtype, calling bitcast on such a ref surfaces this error.","triggerScenarios":"Calling .bitcast(dtype) or accessing .dtype on a ref whose aval has no dtype (non-array aval after transforms).","commonSituations":"Bitcasting refs wrapped around non-standard avals; utility code assuming array-like dtype presence.","solutions":["Verify the ref's type is array-backed before bitcast","Use hasattr/getattr guard on .dtype","Inspect ref.type to understand the transformed aval"],"exampleFix":"// before\nref.bitcast(jnp.int32)\n// after\nif hasattr(ref.type, \"dtype\"):\n    ref.bitcast(jnp.int32)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def has_dtype(ref):\n    return hasattr(getattr(ref, \"type\", ref), \"dtype\")","tryCatchPattern":null,"preventionTips":["Check .type.dtype before bitcast","Validate ref aval kinds in helpers"],"tags":["jax","attribute-error","dtype"],"backgroundTag":"missing-attribute-access","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}