windmill-labs/windmill · error
Cannot parse optional parameter: {}
Error message
Cannot parse optional parameter: {} What it means
The Ruby signature parser (windmill-parser-ruby) walks the tree-sitter AST of `def main(...)` to extract parameter metadata. Optional parameters with syntax the parser does not recognize (beyond simple keyword arguments with defaults it handles) cause a bail with the offending parameter text. This keeps signature extraction honest instead of guessing wrong types.
Source
Thrown at backend/parsers/windmill-parser-ruby/src/lib.rs:160
|e|
anyhow!("Cannot convert default value to json\n\tvalue: {unparsed}\n\terror: {e}{}",
if e.to_string().contains("key must be a string") {
"\n\nNOTE: If you are trying to declare default hash, use following syntax:\n { \"<key>\": <value> }"
} else {
""
}
))?;
args.push(Arg {
name: ident.to_owned(),
typ: json_to_typ(&default, true),
default: Some(default),
has_default: true,
..Default::default()
});
}
_ => {
let Range { start_byte, end_byte, .. } = a.range();
bail!(
"Cannot parse optional parameter: {}",
&code.get(start_byte..end_byte).unwrap_or("CANNOT DISPLAY")
)
}
}
}
let kind = a.kind();
if matches!(
kind,
"keyword_parameter" | "splat_parameter" | "hash_splat_parameter"
) {
let Range { start_byte, end_byte, .. } = a.range();
bail!(
" - {}\n{}s are not supported",
&code.get(start_byte..end_byte).unwrap_or("CANNOT DISPLAY"),
kind.replace("_", " ")
);
}View on GitHub (pinned to e474e8803c)
Solutions
- Make the parameter a keyword parameter with a default (`def main(name: "default")`) which the parser supports
- Remove the optional parameter and hardcode the default inside the function body
- Pass the value explicitly as a Windmill script argument instead of relying on Ruby defaults
Example fix
// before def main(limit = 10) // after def main(limit: 10)
Defensive patterns
Strategy: try-catch
Validate before calling
# ensure main only uses supported keyword params with simple defaults def main(a: 1, b: "x"); end
Try / catch
match parse_ruby_sig_meta(code) {
Err(e) if e.to_string().starts_with("Cannot parse optional parameter") =>
eprintln!("simplify the main signature: {e}"),
Err(e) => return Err(e),
Ok(meta) => { /* proceed */ }
} Prevention
- Use keyword parameters with literal defaults in `def main`
- Avoid optional positional parameters in Windmill Ruby scripts
- Run the parser against new scripts during development
When it happens
Trigger: Defining `def main(...)` in a Ruby script with an optional parameter form the parser's match arms don't cover, e.g. an optional positional parameter or an exotic default expression; raised in `find_main_signature` called from `parse_ruby_sig_meta`.
Common situations: Ruby Windmill scripts with `def main(a = nil)` style optional positional args, splat-adjacent defaults, or default expressions the parser wasn't written to handle.
Related errors
- - {} {}s are not supported
- Aborted from C
- Nesting is not supported
- Failed to parse code
- Invalid gemfile do block
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/02c44223a98a3d28.
Report an issue: GitHub.