windmill-labs/windmill · error

Cannot parse default value for argument

Error message

Cannot parse default value for argument

What it means

parse_nu_signature in windmill-parser-nu locates the `=` that starts an argument's default value and slices the remainder of the batch with `batch.get(d..)` before handing it to parse_default. When that byte range cannot be taken (None from `str::get`), the parser raises this error instead of panicking — it means the default-value portion of the argument is not sliceable at the found offset.

Source

Thrown at backend/parsers/windmill-parser-nu/src/lib.rs:81

            compensate_lookahead -= 1;
            continue;
        }

        let type_start = batch.find(":");
        let default_start = batch.find("=");

        let (name, typ, default) = match (type_start, default_start) {
            (None, None) => (batch.trim(), None, None),
            (None, Some(d)) => (
                batch
                    .get(0..d)
                    .ok_or(anyhow!("Cannot parse argument ident"))?
                    .trim(),
                None,
                Some(parse_default(
                    &batch
                        .get(d..)
                        .ok_or(anyhow!("Cannot parse default value for argument"))?,
                    &batches,
                    i,
                    &mut compensate_lookahead,
                )?),
            ),
            (Some(t), None) => (
                batch
                    .get(0..t)
                    .ok_or(anyhow!("Cannot parse argument ident"))?
                    .trim(),
                Some(parse_type(
                    &batch
                        .get(t..)
                        .ok_or(anyhow!("Cannot parse type of argument"))?,
                )?),
                None,
            ),
            (Some(t), Some(d)) => {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Inspect the `def main [ ... ]` argument list in the script; ensure each argument with a default has well-formed content after `=`, e.g. `x = "foo"`.
  2. Remove dangling `=` markers with no value after them, or give the argument a JSON-serializable default (`string`, number, bool, list, or flat record).
  3. Re-save the file as clean UTF-8; multibyte corruption around the default marker can make the slice impossible.
  4. If the default is a list/record spanning commas, keep it on-parseable lines — nesting (`[[1],[2]]` or records inside records) is not supported and produces related parse bail-outs.

Example fix

// before
def main [x = ] { $x }

// after
def main [x = 42] { $x }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every '=' in def main args is followed by a parseable default value
fn validate_nu_defaults(code: &str) -> Result<(), String> {
    let args = code
        .split("def main").nth(1)
        .and_then(|r| r.split('[').nth(1))
        .and_then(|r| r.split(']').next())
        .ok_or("no def main args")?;
    for batch in args.split(',') {
        let b = batch.trim();
        if let Some(d) = b.find('=') {
            let default = b.get(d..).unwrap_or("").trim_start_matches('=').trim();
            if default.is_empty() {
                return Err(format!("dangling '=' in argument {b:?}"));
            }
        }
    }
    Ok(())
}

Type guard

fn has_sliceable_default(batch: &str, d: usize) -> bool {
    batch.is_char_boundary(d)
        && batch.get(d..).map_or(false, |s| !s.trim_start_matches('=').trim().is_empty())
}

Try / catch

match parse_nu_signature(&nu_code) {
    Ok(sig) => deploy(sig),
    Err(e) if e.to_string().contains("Cannot parse default value") => {
        eprintln!("malformed default value in def main args: {e}");
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: parse_nu_signature is given a Nushell script whose main-args batch contains `=` at byte index `d`, but `get(d..)` fails — e.g. the `=` byte sits at the very end in a corrupted token or a multibyte character sequence makes the range boundary invalid, so the default value text cannot be extracted.

Common situations: A script pasted into Windmill with broken/mixed encodings so the bytes after `=` are invalid in context; hand-edited hub scripts where an argument default was deleted leaving a dangling `=` at the end of a line.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/c491442f699f8e29. Report an issue: GitHub.