windmill-labs/windmill · error
Parsing error `:` should be before `=` it likely means you a
Error message
Parsing error `:` should be before `=` it likely means you are trying to set default value to record or table which is not supported at the moment.
What it means
When parsing `def main` parameters, the parser splits each batch on `:` (type) and `=` (default). If the `=` appears before the `:`, the parameter is shaped like `x = {a: 1}: record` — a default value on a record/table literal — which the grammar cannot represent, so it bails with this explanatory message. Windmill's signature parser does not support assigning defaults to record or table literals in that position.
Source
Thrown at backend/parsers/windmill-parser-nu/src/lib.rs:121
.get(0..t)
.ok_or(anyhow!("Cannot parse argument ident"))?
.trim(),
Some(parse_type(
&batch
.get(t..d)
.ok_or(anyhow!("Cannot parse type of argument"))?,
)?),
Some(parse_default(
&batch
.get(d..)
.ok_or(anyhow!("Cannot parse default value of argument"))?,
&batches,
i,
&mut compensate_lookahead,
)?),
)
} else {
bail!("Parsing error `:` should be before `=`\nit likely means you are trying to set default value to record or table which is not supported at the moment.")
}
}
};
// Check if it is optional
let optional = {
let Some(element) = name.chars().last() else {
bail!("Internal error, cannot check if argument is optional")
};
element == '?'
};
// Rest parameters are not supported
if matches!(name.get(0..3), Some("...")) {
bail!("Rest (...) parameters are not supported")
}
// Flags are not supportedView on GitHub (pinned to e474e8803c)
Solutions
- Remove the default and require the caller to pass the value (use `ident?` optional-with-null if acceptable).
- Annotate the type explicitly before the default: `ident: record = {...}` is still limited — if unsupported, pass records via a JSON resource or input instead.
- Restructure so the default is a supported scalar (string/int/float/bool/list) without `:` in it.
- Handle the record inside the script body: accept `any`/`record` without default and use `default`/`if empty` logic in code.
Example fix
// before
def main [config = {mode: fast}]
// after
def main [mode: string = "fast"] Defensive patterns
Strategy: validation
Validate before calling
function validateNuParamDefaults(sigLine) {
const t = sigLine.indexOf(':'), d = sigLine.indexOf('=');
if (d !== -1 && t !== -1 && d < t) return 'default value appears before type; record/table literal defaults with `:` are not supported — use scalar defaults like `x: string = "a"`';
return null;
} Try / catch
try {
const sig = parseNuSignature(source);
} catch (e) {
if (String(e).includes('`:` should be before `=`')) {
throw new Error('Move the default to a supported scalar form, or drop the default and pass the value at call time');
}
throw e;
} Prevention
- Never use record/table literal defaults ({...: ...}, [[...]]) in def main parameters
- Prefer scalar defaults (string/int/float/bool) or nullable optional params (`ident?`)
- Do complex default construction inside the script body after checking for null
When it happens
Trigger: Declaring a main parameter whose default value contains `:` before the type annotation effectively does — e.g. `def main [config = {mode: fast}]` or `def main [tbl = [[a]; [1]]]`-style record/table literal defaults, where the literal's internal `:` lands after `=` so type_start > default_start.
Common situations: Using a record literal (`{key: value}`) or table literal as a default parameter value in a Nushell script; defaults with colons such as URLs or time literals before a type annotation.
Related errors
- typed records are not supported, use `ident: record`
- Cannot parse default value for argument
- Cannot find main function.
- Internal error, cannot check if argument is optional
- Rest (...) parameters are not supported
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/0b8ac96d413538c2.
Report an issue: GitHub.