slint-ui/slint · info
There is always one line
Error message
There is always one line
What it means
This is an internal invariant panic from `expect("There is always one line")` in `extract_text_of_element` (tools/lsp/preview/drop_location.rs:1051). `String::split('\n')` always yields at least one item, so `lines.last()` is expected to be `Some`. The panic would only fire if `lines` were empty, which the stdlib API makes impossible; it exists to justify unwrapping the last element when computing the element's indentation fallback.
Solutions
- Do not filter or empty the `lines` vec between the `text.split('\n').collect()` and the `lines.last()` call.
- If restructuring, replace `.expect("There is always one line")` with `.unwrap_or("")` so an empty vec degrades to empty indent instead of panicking.
- Keep a unit test that calls extract_text_of_element with a minimal element to pin the non-empty-lines invariant.
Example fix
// before
let indent = util::find_element_indent(element).unwrap_or_else(|| {
lines.last().expect("There is always one line").chars().take_while(|c| c.is_whitespace()).collect()
});
// after
let indent = util::find_element_indent(element).unwrap_or_else(|| {
lines.last().map(|l| l.chars().take_while(|c| c.is_whitespace()).collect()).unwrap_or_default()
}); Defensive patterns
Strategy: fallback
Validate before calling
let lines: Vec<&str> = text.split('\n').collect();
assert!(!lines.is_empty(), "split always yields at least one line"); Type guard
fn last_line(lines: &[&str]) -> Option<&str> { lines.last().copied() } Try / catch
// Rust: no catch; replace expect with unwrap_or at the call site lines.last().map(|l| l.chars().take_while(|c| c.is_whitespace()).collect()).unwrap_or_default()
Prevention
- Never filter the lines vec between split and last().
- Prefer Option-combining (map/unwrap_or_default) over expect for derivable invariants.
- Add regression tests for extract_text_of_element with empty and single-line elements.
When it happens
Trigger: Only reachable if the invariant 'split always returns >=1 line' were broken — e.g. if the code were refactored to filter/trim `lines` before this point, or the `text` string were replaced by an empty collection. Not triggerable from any public API with the current source.
Common situations: Developers hit this only after refactoring `extract_text_of_element` so that the `lines` vec can become empty before line 1048 (e.g. filtering out blank lines), or when reimplementing the indentation logic and dropping the `split` that guarantees a non-empty vec.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Not empty
- Global was just valid
- Length was checked
- an identifier
- EditorSession must have at least one preview
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/12f3289ca910ac59.
Report an issue: GitHub.
Appendix: source
Thrown at tools/lsp/preview/drop_location.rs:1051
let mut to_delete_ranges = property_ranges(element, remove_properties);
to_delete_ranges.sort_by(|a, b| u32::from(a.start()).cmp(&u32::from(b.start())));
let mut offset = start_offset;
for dr in to_delete_ranges {
let start = usize::from(dr.start()) - offset;
let end = usize::from(dr.end()) - offset;
offset += end - start;
text.drain(start..end);
}
// Trim leading WS to get "raw" lines
let lines = text.split('\n').collect::<Vec<_>>();
let indent = util::find_element_indent(element).unwrap_or_else(|| {
lines
.last()
.expect("There is always one line")
.chars()
.take_while(|c| c.is_whitespace())
.collect()
});
lines
.iter()
.map(|l| if l.starts_with(&indent) { l[indent.len()..].to_string() } else { l.to_string() })
.collect::<Vec<_>>()
}
fn node_removal_text_edit(
document_cache: &editor_preview::DocumentCache,
node: &SyntaxNode,
replace_with: String,
) -> Option<editor_preview::editing::SingleTextEdit> {
let range = util::text_range_to_lsp_range(
&node.source_file.clone(),View on GitHub (pinned to bb937076de)