{"record":{"id":"5685fa2e73b34777","repo":"jax-ml/jax","slug":"array-contains-query-value-must-be-a-scalar","errorCode":null,"errorMessage":"Array.__contains__: query value must be a scalar, got {query.shape=}","messagePattern":"Array\\.__contains__: query value must be a scalar, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/numpy/array_methods.py","lineNumber":220,"sourceCode":"\ndef _contains(self: Array, other: ArrayLike) -> Array:\n  \"\"\"Implements __contains__ for JAX arrays.\n\n  This is used by the Python ``in`` operator.\n  \"\"\"\n  # Note: we deliberately depart from NumPy's behavior here, which includes\n  # some oddities (https://github.com/numpy/numpy/issues/21933). Namely, we\n  # require `self` to be a 1D array, and require `other` to be a scalar.'\n\n  # Explicitly check for string and None types, as these were common bugs.\n  if other is None or isinstance(other, str):\n    raise TypeError(f\"Array.__contains__: unsupported operand type {type(other)}.\")\n  query = util.ensure_arraylike('Array.__contains__', other)\n  if self.ndim != 1:\n    raise ValueError(\"Array.__contains__: search array must be one-dimensional,\"\n                     f\" got arr.shape={self.shape}.\")\n  if query.ndim != 0:\n    raise ValueError(\"Array.__contains__: query value must be a scalar,\"\n                     f\" got {query.shape=}\")\n  return reductions.any(self == query)\n\ndef _copy(self: Array) -> Array:\n  \"\"\"Return a copy of the array.\n\n  Refer to :func:`jax.numpy.copy` for the full documentation.\n  \"\"\"\n  return lax_numpy.copy(self)\n\ndef _cumprod(self: Array, axis: int | None = None,\n             dtype: DTypeLike | None = None, out: None = None) -> Array:\n  \"\"\"Return the cumulative product of the array.\n\n  Refer to :func:`jax.numpy.cumprod` for the full documentation.\n  \"\"\"\n  return reductions.cumprod(self, axis=axis, dtype=dtype, out=out)\n","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/numpy/array_methods.py#L202-L238","documentation":"jax.Array.__contains__ requires the query (right operand of `in`) to be a scalar; NumPy allows array-like queries. JAX restricts this to keep semantics simple and to avoid ambiguity about what array-in-array containment means. The message includes the query's shape.","triggerScenarios":"Calling `query in arr` where `query` is a 0-d-or-higher jnp/np array with ndim != 0, e.g. `jnp.array([1,2]) in jnp_array`.","commonSituations":"Porting NumPy code that tests array containment; mistakenly wrapping the query value in jnp.array or np.array before the membership test.","solutions":["Use set-style logic instead: `jnp.isin(arr, query).any()`","Pass a true scalar: `float(query) in arr`","For subset checks use `jnp.isin` directly"],"exampleFix":"# before\njnp.array([1., 2.]) in arr\n\n# after\njnp.isin(jnp.array([1., 2.]), arr).all()","handlingStrategy":"validation","validationCode":"import jax.numpy as jnp\n\ndef member(arr, q):\n    q = jnp.asarray(q)\n    if q.ndim != 0:\n        return bool(jnp.isin(q, arr).all())\n    return bool(q in arr)","typeGuard":"def is_scalar_like(q) -> bool:\n    return jnp.asarray(q).ndim == 0","tryCatchPattern":null,"preventionTips":["Don't wrap query values in arrays before `in`","Use jnp.isin for array-vs-array containment"],"tags":["jax","membership","scalar-required","contains"],"backgroundTag":"shape-validation-failed","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}