slint-ui/slint · error
insertion index (is ) should be <= len (is )
Error message
insertion index (is {row}) should be <= len (is {len}) What it means
SharedVector::insert panics when the insertion index exceeds the current length (row > len). Inserting at exactly len is allowed (append), but anything beyond leaves a gap, so the guard panics before the unsafe element shift. Mirrors Vec::insert's panic semantics.
Solutions
- Clamp the index before inserting: `let row = row.min(vec.len())`
- Check `if row <= vec.len()` before calling insert
- Verify the index source (model row count, list selection) matches this vector's current length
Example fix
// before vec.insert(index, value); // after let index = index.min(vec.len()); vec.insert(index, value);
Defensive patterns
Strategy: validation
Validate before calling
let row = row.min(vec.len()); vec.insert(row, value);
Prevention
- Clamp insertion indices to the current length
- Distinguish append (row == len, allowed) from out-of-range inserts (row > len, panics)
- Re-check the vector's length whenever the index comes from another collection
When it happens
Trigger: Calling `vec.insert(row, value)` where row > vec.len() — e.g. inserting at an index computed from a different collection's length, inserting into an empty vector at a nonzero index, or using a stale index after the vector shrank.
Common situations: Model insert_row implementations passing UI-supplied positions beyond the data length; arithmetic errors when combining indices; copying indices between similarly-named but differently-sized vectors.
Related errors
- removal index (is ) should be < len (is )
- Length was checked
- a setter belongs to a field
- an identifier
- binding was of the wrong type
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/00b8d9f7d7db0d65.
Report an issue: GitHub.
Appendix: source
Thrown at internal/core/sharedvector.rs:273
self.detach(len);
unsafe {
let data = data_ptr(self.inner);
let value = core::ptr::read(data.add(row));
let size = (*self.inner.as_ptr()).header.size;
core::ptr::copy(data.add(row + 1), data.add(row), size - 1 - row);
(*self.inner.as_ptr()).header.size = size - 1;
value
}
}
/// Inserts the element at the given index in the array, shifting the following elements.
/// If the array was shared, this will make a copy of the array.
///
/// Panics if `row > len`.
pub fn insert(&mut self, row: usize, value: T) {
let len = self.len();
if row > len {
panic!("insertion index (is {row}) should be <= len (is {len})");
}
self.detach(capacity_for_grow(self.capacity(), self.len() + 1, core::mem::size_of::<T>()));
unsafe {
let data = data_ptr(self.inner);
let size = (*self.inner.as_ptr()).header.size;
core::ptr::copy(data.add(row), data.add(row + 1), size - row);
core::ptr::write(data.add(row), value);
(*self.inner.as_ptr()).header.size = size + 1;
}
}
/// Removes last element from the array and returns it.
/// If the array was shared, this will make a copy of the array.
pub fn pop(&mut self) -> Option<T> {
if self.is_empty() {
None
} else {
self.detach(self.len());View on GitHub (pinned to bb937076de)