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

  1. Normalize the input: ensure every line is prefixed with the same whitespace before calling unindent (e.g. use the indoc crate instead).
  2. Trim lines defensively: skip/clip lines shorter than `min` before slicing.
  3. Replace the hand-rolled unindent with `indoc::indoc!` or `unindent` crate, which handle edge cases.
  4. 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

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


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: &regex::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)