elkowar/eww · warning
Something went wrong unindenting the string
Error message
Something went wrong unindenting the string
What it means
unindent strips a common leading-space indent from each line by slicing &i[min..]. The writeln!(...) expect fires if slicing/formatting panics — in practice when min exceeds a line's char length, so the slice start is out of bounds. It is a logic guard in the string-unindenting helper.
Solutions
- Normalize the input: ensure every line is prefixed with the same whitespace before calling unindent (e.g. use the indoc crate instead).
- Trim lines defensively: skip/clip lines shorter than `min` before slicing.
- Replace the hand-rolled unindent with `indoc::indoc!` or `unindent` crate, which handle edge cases.
- Compute `min` as a byte index consistently and clamp it: `let start = min.min(i.len());` before slicing.
Example fix
// before
for i in lines {
writeln!(result, "{}", &i[min..]).expect("Something went wrong unindenting the string");
}
// after
for i in lines {
let start = min.min(i.len());
writeln!(result, "{}", &i[start..]);
} Defensive patterns
Strategy: validation
Validate before calling
// guard before slicing
if line.len() < min { continue; } // or clamp: let start = min.min(line.len()); Try / catch
// slicing panic; avoid by clamping the index instead of catching
let start = min.min(i.len());
writeln!(result, "{}", &i[start..]).ok(); Prevention
- Normalize whitespace (expand tabs to spaces) before unindenting
- Prefer the indoc or unindent crates over hand-rolled slicing
- Use char_indices/char-aware offsets consistently
- Add tests with empty lines and mixed indentation
When it happens
Trigger: Calling unindent on text where the computed common indent `min` (computed over chars) is larger than the byte/char length of some line — e.g. lines mixing indentation such that `min` derived from char counts misaligns with byte indexing used by `[min..]`, or a line shorter than min.
Common situations: Developers using eww's util::unindent on hand-built multi-line strings with inconsistent leading whitespace, tabs mixed with spaces, or trailing empty lines with fewer characters than the indent — mostly hit in tests or when generating inline templates/docs.
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
- Error opening log file
- OneToNElementsMap got into inconsistent state
- No root scope in graph
- Could not get default gtk theme
- no pixbuf from theme.load_icon despite no error
AI-assisted analysis of elkowar/eww@48f5aa8b37 (2026-09-08).
Data as JSON: /api/errors/365a2c9a55fd6664.
Report an issue: GitHub.
Appendix: source
Thrown at crates/eww/src/util.rs:128
.replace_all(&input, |var_name: ®ex::Captures| std::env::var(var_name.get(1).unwrap().as_str()).unwrap_or_default())
.into_owned()
}
pub fn unindent(text: &str) -> String {
// take all the lines of our text and skip over the first empty ones
let lines = text.lines().skip_while(|x| x.is_empty());
// find the smallest indentation
let min = lines
.clone()
.fold(None, |min, line| {
let min = min.unwrap_or(usize::MAX);
Some(min.min(line.chars().take(min).take_while(|&c| c == ' ').count()))
})
.unwrap_or(0);
let mut result = String::new();
for i in lines {
writeln!(result, "{}", &i[min..]).expect("Something went wrong unindenting the string");
}
result.pop();
result
}
#[cfg(test)]
mod test {
use super::{replace_env_var_references, unindent};
#[test]
fn test_replace_env_var_references() {
let scss = "$test: ${USER};";
assert_eq!(
replace_env_var_references(String::from(scss)),
format!("$test: {};", std::env::var("USER").unwrap_or_default())
)
}View on GitHub (pinned to 48f5aa8b37)