{"record":{"id":"b4c69358f8febf09","repo":"jax-ml/jax","slug":"expected-a-string-or-dtype-like-object-got-dtype","errorCode":null,"errorMessage":"Expected a string or dtype-like object; got {dtype=}","messagePattern":"Expected a string or dtype-like object; got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/dlpack.py","lineNumber":57,"sourceCode":"# For example,\n# hash(jnp.float32) != hash(jnp.dtype(jnp.float32))\n# hash(jnp.float32) == hash(jnp.dtype(jnp.float32).type)\n\n# TODO(vanderplas): remove this set\nSUPPORTED_DTYPES: frozenset[DTypeLike] = frozenset({\n    jnp_types.int8, jnp_types.int16, jnp_types.int32, jnp_types.int64,\n    jnp_types.uint8, jnp_types.uint16, jnp_types.uint32, jnp_types.uint64,\n    jnp_types.float16, jnp_types.bfloat16, jnp_types.float32, jnp_types.float64,\n    jnp_types.complex64, jnp_types.complex128, jnp_types.bool_})\n\nSUPPORTED_DTYPES_SET: frozenset[np.dtype] = frozenset({np.dtype(dt) for dt in SUPPORTED_DTYPES})\n\n\ndef is_supported_dtype(dtype: DTypeLike) -> bool:\n  \"\"\"Check if dtype is supported by jax.dlpack.\"\"\"\n  if dtype is None:\n    # NumPy will silently cast this to float64, which may be surprising.\n    raise TypeError(f\"Expected a string or dtype-like object; got {dtype=}\")\n  return np.dtype(dtype) in SUPPORTED_DTYPES_SET\n\n\ndef _to_dlpack(x: Array, stream: int | Any | None,\n               src_device: _jax.Device | None = None,\n               device: _jax.Device | None = None,\n               copy: bool | None = None):\n\n  if src_device is None:\n    src_device, = x.devices()\n  if device and (src_device is None or device != src_device):\n    if copy is not None and not copy:\n      raise ValueError(\n        f\"Specified {device=} which requires a copy since the source device \"\n        f\"is {repr(src_device)}, however copy=False. Set copy=True or \"\n        \"copy=None to perform the requested operation.\"\n      )\n    else:","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/dlpack.py#L39-L75","documentation":"jax.dlpack.is_supported_dtype rejects dtype=None because NumPy would silently interpret None as float64, producing a surprising dtype instead of an error. JAX raises an explicit TypeError instead.","triggerScenarios":"Calling jax.dlpack.is_supported_dtype(None), or passing an unpopulated dtype variable (common when a dtype field of a config/dataclass defaults to None) into dlpack conversion.","commonSituations":"Optional dtype parameters threaded from user config into from_dlpack/to_dlpack paths; passing torch tensors' dtype when it is None.","solutions":["Default the dtype explicitly (e.g. `dtype or torch.float32`) before calling","Validate dtype is not None with an isinstance/type check upstream","Pass a concrete numpy/torch dtype string such as 'float32'"],"exampleFix":"# before\njax.dlpack.is_supported_dtype(cfg.dtype)  # cfg.dtype is None\n\n# after\ndtype = cfg.dtype or 'float32'\njax.dlpack.is_supported_dtype(dtype)","handlingStrategy":"type-guard","validationCode":"if dtype is None:\n    raise ValueError('dtype must be specified for dlpack conversion')\njax.dlpack.is_supported_dtype(dtype)","typeGuard":"def has_dtype(d) -> bool:\n    return d is not None and not isinstance(d, type(None))","tryCatchPattern":"try:\n    jax.dlpack.is_supported_dtype(dtype)\nexcept TypeError:\n    dtype = 'float32'","preventionTips":["Default optional dtype fields to a concrete dtype","Never pass None where a dtype-like is documented"],"tags":["jax","dlpack","dtype","none-guard"],"backgroundTag":"none-value-validation","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}