pandas-dev/pandas · error · ValueError

Cannot slice with

Error message

Cannot slice with '{key}'

What it means

ValueError raised at the tail of SparseArray.__getitem__ when the normalized key lacks __len__ and is not a recognized scalar/slice type, so the array cannot decide between take and slice semantics.

Solutions

  1. Convert the key to a concrete array via np.asarray(key) before indexing.
  2. Use arr.take(indices) explicitly with an integer array.
  3. Simplify to a slice or integer key.

Example fix

// before
arr[my_custom_key]  # raises
// after
arr[np.asarray(my_custom_key)]
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
def normalize_key(key):
    return np.asarray(key) if not hasattr(key, '__len__') and not isinstance(key, slice) else key

Type guard

def key_is_indexable(key) -> bool:
    return isinstance(key, slice) or hasattr(key, '__len__') or isinstance(key, int)

Try / catch

try:
    arr[key]
except ValueError as e:
    if "Cannot slice with" in str(e):
        out = arr[np.asarray(key)]
    else:
        raise

Prevention

When it happens

Trigger: Passing an exotic indexable (e.g. a 0-d object, a custom type) that survives earlier branches but exposes neither boolean indexing nor __len__.

Common situations: Custom index types passed to a SparseArray; pandas internals forwarding unexpected key objects.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/c001156511bc3a5f. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/sparse/array.py:1130

                    if not key.fill_value:
                        return self.take(key.sp_index.indices)
                    n = len(self)
                    mask = np.full(n, True, dtype=np.bool_)
                    mask[key.sp_index.indices] = False
                    return self.take(np.arange(n)[mask])
                else:
                    key = np.asarray(key)

            key = check_array_indexer(self, key)

            if com.is_bool_indexer(key):
                # mypy doesn't know we have an array here
                key = cast("np.ndarray", key)
                return self.take(np.arange(len(key), dtype=np.int32)[key])
            elif hasattr(key, "__len__"):
                return self.take(key)
            else:
                raise ValueError(f"Cannot slice with '{key}'")

        return type(self)(data_slice, kind=self.kind)

    def _get_val_at(self, loc):
        n = len(self)
        if loc < 0:
            loc += n

        if loc >= n or loc < 0:
            raise IndexError(
                f"index is out of bounds: must be an integer between -{n} and {n - 1}"
            )

        sp_loc = self.sp_index.lookup(loc)
        if sp_loc == -1:
            return self.fill_value
        else:
            val = self.sp_values[sp_loc]

View on GitHub (pinned to 3b7651241d)