slint-ui/slint · error · IndexError
row index out of range
Error message
row index out of range
What it means
SlintPyListModel.remove_row performs explicit bounds validation against the Python list backing the model and raises IndexError when row is negative or >= len(self.list). It means the caller asked to delete a row that does not exist — commonly a stale index after a previous removal, or code that used the row count instead of count-1. The list is left unchanged when this fires.
Solutions
- Check 0 <= row < model.row_count() before calling remove_row.
- Recompute indices after each deletion instead of reusing stale positions.
- Wrap the call in try/except IndexError to tolerate already-removed rows.
Example fix
# before
model.remove_row(idx) # IndexError if idx stale
# after
if 0 <= idx < model.row_count():
model.remove_row(idx) Defensive patterns
Strategy: validation
Validate before calling
def safe_remove(model, row):
if not 0 <= row < model.row_count():
return False
model.remove_row(row)
return True Try / catch
try:
model.remove_row(idx)
except IndexError:
pass # already removed Prevention
- Always check row_count() before deleting by index.
- Recompute indices after each mutation; never reuse cached positions across callbacks.
When it happens
Trigger: Calling list_model.remove_row(negative) or remove_row(index >= row_count); removing from a stale index after the model shrank; concurrent modifications invalidating a cached index.
Common situations: UI code caching row indices while other callbacks delete rows; off-by-one loops (`for i in range(len+1)`); deleting the same row twice.
Related errors
- does not support inserting rows
- does not support removing rows
- Callback ' ' cannot be used with a callback decorator for…
- Callback ' ' cannot be used with a callback decorator for…
- Callback ' ' in global ' ' cannot be used with a callback…
AI-assisted analysis of slint-ui/slint@3a7e700487 (2026-09-16).
Data as JSON: /api/errors/286c64e147034baa.
Report an issue: GitHub.
Appendix: source
Thrown at api/python/slint/slint/models.py:131
self.list: list[T]
if iterable is not None:
self.list = list(iterable)
else:
self.list = []
def row_count(self) -> int:
return len(self.list)
def row_data(self, row: int) -> T | None:
return self.list[row]
def set_row_data(self, row: int, value: T) -> None:
self.list[row] = value
super().notify_row_changed(row if row >= 0 else row + len(self.list))
def remove_row(self, row: int) -> None:
if row < 0 or row >= len(self.list):
raise IndexError("row index out of range")
del self.list[row]
super().notify_row_removed(row, 1)
def insert_row(self, row: int, value: T) -> None:
if row < 0 or row > len(self.list):
raise IndexError("row index out of range")
self.insert(row, value)
def __delitem__(self, key: int | slice) -> None:
if isinstance(key, slice):
rows = range(*key.indices(len(self.list)))
if not rows:
return
if abs(rows.step) == 1:
first = rows.start if rows.step > 0 else rows[-1]
del self.list[key]
super().notify_row_removed(first, len(rows))
else:View on GitHub (pinned to 3a7e700487)