keras-team/keras · error · ValueError

Asked to retrieve element {idx}, but the Sequence has length

Error message

Asked to retrieve element {idx}, but the Sequence has length {length}

What it means

keras.utils.Sequence (legacy image preprocessing Iterator) bounds-checks __getitem__: requesting a batch index >= the number of batches raises this ValueError. It guards index_array access so an out-of-range request fails fast instead of returning garbage.

Source

Thrown at keras/src/legacy/preprocessing/image.py:59

        super().__init__(**kwargs)
        self.n = n
        self.batch_size = batch_size
        self.seed = seed
        self.shuffle = shuffle
        self.batch_index = 0
        self.total_batches_seen = 0
        self.lock = threading.Lock()
        self.index_array = None
        self.index_generator = self._flow_index()

    def _set_index_array(self):
        self.index_array = np.arange(self.n)
        if self.shuffle:
            self.index_array = np.random.permutation(self.n)

    def __getitem__(self, idx):
        if idx >= len(self):
            raise ValueError(
                "Asked to retrieve element {idx}, "
                "but the Sequence "
                "has length {length}".format(idx=idx, length=len(self))
            )
        if self.seed is not None:
            np.random.seed(self.seed + self.total_batches_seen)
        self.total_batches_seen += 1
        if self.index_array is None:
            self._set_index_array()
        index_array = self.index_array[
            self.batch_size * idx : self.batch_size * (idx + 1)
        ]
        return self._get_batches_of_transformed_samples(index_array)

    def __len__(self):
        return (self.n + self.batch_size - 1) // self.batch_size  # round up

    def on_epoch_end(self):

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Index with idx < len(sequence) - derive bounds from len(seq) or floor(n / batch_size)
  2. Recompute steps_per_epoch whenever batch_size or dataset size changes
  3. Iterate with enumerate(sequence) instead of manual indices

Example fix

# before
for i in range(1000):
    batch = seq[i]

# after
for i in range(len(seq)):
    batch = seq[i]
Defensive patterns

Strategy: type-guard

Validate before calling

assert 0 <= idx < len(seq)

Type guard

def valid_index(seq, i): return isinstance(i, int) and 0 <= i < len(seq)

Try / catch

try:
    batch = seq[idx]
except ValueError as e:
    if 'has length' in str(e):
        raise IndexError(f'{idx} out of range for {len(seq)} batches') from e
    raise

Prevention

When it happens

Trigger: Calling iterator[i] or Sequence.__getitem__ with idx >= number of batches; using a len computed before changing batch_size; iterating with a hardcoded range after the dataset shrinks.

Common situations: Custom training loops that compute steps_per_epoch from an older batch_size, resuming after reducing the dataset, multiprocessing workers with cached lengths.

Related errors


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/416932f5c1a04811. Report an issue: GitHub.