zed-industries/zed · error

percentage must be between 0 and 100, got {}

Error message

percentage must be between 0 and 100, got {}

What it means

Bailed while parsing a `ep split` spec like `train.jsonl=80%`: the percentage parsed as a number but fell outside the inclusive 0–100 range. Percentages are whole-range values (80 means 80%, not 0.8), and values are validated before any file is read.

Source

Thrown at crates/edit_prediction_cli/src/split_dataset.rs:135

pub struct SplitSpec {
    pub path: PathBuf,
    pub size: SplitSize,
}

fn parse_split_spec(spec: &str) -> Result<SplitSpec> {
    let (path, size_str) = spec
        .rsplit_once('=')
        .with_context(|| format!("invalid split spec '{}': expected <path>=<size>", spec))?;

    let size = if size_str == "rest" {
        SplitSize::Rest
    } else if size_str.ends_with('%') {
        let pct_str = size_str.trim_end_matches('%');
        let pct: f64 = pct_str
            .parse()
            .with_context(|| format!("invalid percentage '{}' in '{}'", pct_str, spec))?;
        if !(0.0..=100.0).contains(&pct) {
            bail!("percentage must be between 0 and 100, got {}", pct);
        }
        SplitSize::Percentage(pct / 100.0)
    } else {
        let count: usize = size_str
            .parse()
            .with_context(|| format!("invalid count '{}' in '{}'", size_str, spec))?;
        SplitSize::Absolute(count)
    };

    Ok(SplitSpec {
        path: PathBuf::from(path),
        size,
    })
}

fn read_lines_from_input(input: Option<&Path>) -> Result<Vec<String>> {
    let reader: Box<dyn BufRead> = match input {
        Some(path) => {

View on GitHub (pinned to f4178619ac)

Solutions

  1. Keep each percentage in 0–100 inclusive
  2. Express fractional intent as 80, not 0.8
  3. Use the `rest` keyword on one split to absorb leftovers instead of forcing percentages to sum exactly

Example fix

# before
ep split data.jsonl train.jsonl=0.8 valid.jsonl=0.2

# after
ep split data.jsonl train.jsonl=80% valid.jsonl=20%
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_percentage(text: &str) -> bool {
    text.strip_suffix('%')
        .and_then(|t| t.parse::<f64>().ok())
        .map(|p| (0.0..=100.0).contains(&p))
        .unwrap_or(false)
}

Type guard

fn is_valid_percentage(text: &str) -> bool {
    text.strip_suffix('%')
        .and_then(|t| t.parse::<f64>().ok())
        .map(|p| (0.0..=100.0).contains(&p))
        .unwrap_or(false)
}

Try / catch

Validate every `<path>=<size>` spec string before invoking the split command; report all invalid specs at once instead of failing on the first.

Prevention

When it happens

Trigger: Passing `train.jsonl=120%`, `valid.jsonl=-5%`, or `train.jsonl=0.8%` (fraction expressed as if it were a percentage) to `ep split`.

Common situations: Assuming percentages are fractions (0.8 instead of 80); three-way splits accidentally summing over 100; typos.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/6a5aad0707dff137. Report an issue: GitHub.