windmill-labs/windmill · error

Error parsing powershell script

Error message

Error parsing powershell script

What it means

`parse_powershell_sig` extracts a PowerShell script's parameters from a top-level `param(...)` block (including [Parameter(...)] attributes and [CmdletBinding()]). If the script has no param block matching the parser's grammar, it returns this error instead of a signature.

Source

Thrown at backend/parsers/windmill-parser-bash/src/lib.rs:103

        };

        Ok(MainArgSignature {
            star_args: false,
            star_kwargs: false,
            args,
            auto_kind: None,
            has_preprocessor: None,
            has_cmd_binding: if has_cmd_binding { Some(true) } else { None },
            supports_should_process: if supports_should_process {
                Some(true)
            } else {
                None
            },

            ..Default::default()
        })
    } else {
        Err(anyhow!("Error parsing powershell script".to_string()))
    }
}

lazy_static::lazy_static! {
    static ref RE_BASH: Regex = Regex::new(r#"(?m)^(\w+)="\$(?:(\d+)|\{(\d+)\}|\{(\d+):-(.*)\})"(?:[\t ]*)?(?:#.*)?\r?$"#).unwrap();
}

fn parse_bash_file(code: &str) -> anyhow::Result<Option<Vec<Arg>>> {
    let mut hm: HashMap<i32, (String, Option<String>)> = HashMap::new();
    for cap in RE_BASH.captures_iter(code) {
        hm.insert(
            cap.get(2)
                .or(cap.get(3))
                .or(cap.get(4))
                .and_then(|x| x.as_str().parse::<i32>().ok())
                .ok_or_else(|| anyhow!("Impossible to parse arg digit"))?,
            (
                cap[1].to_string(),

View on GitHub (pinned to e474e8803c)

Solutions

  1. Declare script parameters in a top-level `param(...)` block at the very start of the script, one `[type]$name = $default` per line
  2. If using [CmdletBinding()] or [Parameter(Mandatory)] attributes, keep them in the standard form the parser recognizes (see the parser's own tests for accepted forms)
  3. Move any function-scoped param intended as a script parameter up to script scope
  4. If no typed params are needed, define them through Windmill's script metadata/UI

Example fix

# before
function Main($name) { ... }; Main -name $args[0]
# after
param(
    [string]$name = "world"
)
# body uses $name directly
Defensive patterns

Strategy: validation

Validate before calling

// must have a top-level param block
/^\s*(\[CmdletBinding\(\)\]\s*)?param\s*\(/.test(code.trimStart());

Type guard

function hasParseablePwshParams(code) {
  return /^\s*(\[CmdletBinding\(\)\]\s*)?param\s*\(/m.test(code.trimStart());
}

Try / catch

try { sig = parsePowershellSig(code); } catch (e) {
  if (e.message === 'Error parsing powershell script') {
    // use manually defined signature from script metadata
  } else throw e;
}

Prevention

When it happens

Trigger: Parsing a PowerShell script whose parameters aren't declared in a recognized top-level `param(...)` block — no param block at all, params only via $args, a param nested inside a function, or attribute formatting the parser's regexes don't cover.

Common situations: Scripts relying only on $args; param block placed after other statements (PowerShell requires param first anyway); advanced attribute syntax the parser doesn't support; empty or scaffold scripts.

Related errors


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