databendlabs/databend · error

transfer target page index is out of bounds

Error message

transfer target page index is out of bounds

What it means

Same commit() path as the payload-index panic, but here the target payload exists and payload.pages.get_mut(page_index) returns None: the recorded page index is out of bounds for the destination payload's pages. It indicates the state transfer offsets were recorded against pages that no longer exist.

Solutions

  1. Ensure pages of the target payload are not freed/compacted between recording transfer offsets and calling commit.
  2. Validate page_index < payload.pages.len() when recording the offset to fail fast with context.
  3. Recompute the transfer offsets from the current arena state instead of reusing stale records.
  4. Report the failing query plan; this is an internal invariant violation.
Defensive patterns

Strategy: validation

Validate before calling

assert!(page_index < payload.pages.len(), "transfer offset references invalid page {}", page_index);

Prevention

When it happens

Trigger: commit_transferred_state_offsets committing an offset whose page_index >= payload.pages.len() for the target payload — e.g. pages evicted/compacted after offsets were recorded.

Common situations: Aggregate state transfer across payload arenas during multi-phase aggregation (partial → final) where page allocation or recycling changes between recording and commit.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/6bea1c765adf1ebe. Report an issue: GitHub.

Appendix: source

Thrown at src/query/expression/src/aggregate/payload.rs:100

impl PayloadTransferStateOffsets {
    fn record(&mut self, payload_index: usize, offsets: Vec<(usize, usize)>) {
        self.offsets.extend(
            offsets
                .into_iter()
                .map(|(page_index, offset)| (payload_index, page_index, offset)),
        );
    }

    fn commit(self, payloads: &mut [Payload]) {
        for (payload_index, page_index, offset) in self.offsets {
            let payload = payloads
                .get_mut(payload_index)
                .expect("transfer target payload index is out of bounds");

            let page = payload
                .pages
                .get_mut(page_index)
                .expect("transfer target page index is out of bounds");
            let next_state_offsets = page
                .state_offsets
                .checked_add(offset)
                .expect("transfer target state offsets overflow");
            let initialized_states = page
                .rows
                .checked_mul(payload.aggrs.len())
                .expect("transfer target initialized states overflow");

            assert!(
                next_state_offsets <= initialized_states,
                "transfer target state offsets exceed initialized aggregate states"
            );
            page.state_offsets = next_state_offsets;
        }
    }
}

View on GitHub (pinned to 288d84d76e)