{"record":{"id":"a884b84b28b46626","repo":"jax-ml/jax","slug":"array-contains-search-array-must-be-one-dimen","errorCode":null,"errorMessage":"Array.__contains__: search array must be one-dimensional, got arr.shape={self.shape}.","messagePattern":"Array\\.__contains__: search array must be one-dimensional, got arr\\.shape=(.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/numpy/array_methods.py","lineNumber":217,"sourceCode":"  Refer to :func:`jax.numpy.conjugate` for the full documentation.\n  \"\"\"\n  return ufuncs.conjugate(self)\n\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.","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/numpy/array_methods.py#L199-L235","documentation":"jax.Array.__contains__ requires the array being searched to be one-dimensional, unlike NumPy which flattens. This is a deliberate JAX design choice to avoid NumPy's surprising `in` behavior on multi-dimensional arrays. The error reports the actual shape of the array.","triggerScenarios":"Executing `scalar in arr` where `arr` is a jax.Array with ndim != 1 (e.g. shape (3, 4) or ()).","commonSituations":"Reusing NumPy code that used `in` on matrices; forgetting to select a row/column (`arr[i] in matrix` vs `x in matrix[i]`); applying membership tests to batched tensors.","solutions":["Flatten first: `scalar in arr.flatten()` or `scalar in arr.ravel()`","Index/select a 1D slice: `scalar in arr[i]`","Use an explicit reduction: `bool(jnp.any(arr == scalar))`"],"exampleFix":"# before\n3.0 in matrix  # matrix.shape == (3, 4)\n\n# after\n3.0 in matrix.flatten()","handlingStrategy":"validation","validationCode":"def contains_1d(arr, x):\n    assert arr.ndim == 1, f'expected 1D, got {arr.shape}'\n    return bool(x in arr)","typeGuard":"def is_1d(a) -> bool:\n    return getattr(a, 'ndim', -1) == 1","tryCatchPattern":null,"preventionTips":["Prefer jnp.any(arr == x) which works for any ndim","Flatten before membership tests when porting NumPy code"],"tags":["jax","membership","shape-mismatch","contains"],"backgroundTag":"shape-validation-failed","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}