xai-org/x-algorithm · error · ParseFailure
Non-optional parameter %s must be declared before optional p
Error message
Non-optional parameter %s must be declared before optional parameters.
What it means
Enforced by Parser.buildParams: once a parameter with a default value (optional parameter) appears, no later parameter may omit a default. This mirrors the Java/Scala rule that optional/defaulted parameters must trail required ones, keeping positional argument construction unambiguous.
Source
Thrown at botmaker/src/java/com/twitter/botmaker/compiler/Parser.java:176
"Failed to parse DF signature '%s'%s", s, extraMsg), re);
}
throw new ParseFailure("unknown parse failure", e);
}
return buildParams(root);
}
private static ImmutableList<Tuple3<Tree, String, Optional<Tree>>> buildParams(
Tree params) throws ParseFailure {
ImmutableList.Builder<Tuple3<Tree, String, Optional<Tree>>> ret = ImmutableList.builder();
Set<String> argNames = Sets.newHashSet();
boolean hasOpt = false;
for (int i = 0; i < params.getChildCount(); i++) {
Tree arg = params.getChild(i);
if (arg.getType() == BotMakerLexer.ARG) {
String name = arg.getChild(1).getText();
if (arg.getChildCount() == 2 && hasOpt) {
throw new ParseFailure(
String.format(
"Non-optional parameter %s must be declared before optional parameters.",
name));
} else if (arg.getChildCount() == 2) {
ret.add(Tuple.of(arg.getChild(0), name, Optional.absent()));
} else {
hasOpt = true;
ret.add(Tuple.of(arg.getChild(0), name, Optional.of(arg.getChild(2))));
}
if (argNames.contains(name)) {
throw new ParseFailure("Duplicated argument name " + name);
}
argNames.add(name);
}
}
return ret.build();
}View on GitHub (pinned to 24c60942c5)
Solutions
- Give the trailing non-optional parameter a default value, or move it before the first optional parameter
- If the parameter must be required, make all preceding optional parameters required too
- Add a lint/unit test over signature definitions to catch ordering violations at build time
Example fix
// before #params(x, opt=1, required) // after #params(required, x, opt=1)
Defensive patterns
Strategy: validation
Validate before calling
// Validate before parsing: required params must precede optional ones
boolean validOrder(List<Param> ps) {
boolean seenOpt = false;
for (Param p : ps) {
if (p.defaultValue.isPresent()) seenOpt = true;
else if (seenOpt) return false;
}
return true;
} Try / catch
try { Parser.parseParams(sig); } catch (ParseFailure pf) { /* message names the offending param */ } Prevention
- Treat 'append required param at end' edits as a red flag
- Add a build-time lint over all DF signatures
- Encode the rule in code review checklists
When it happens
Trigger: A params/DF signature like #param(a, b=1, c) where c has no default but follows optional b. Detected while iterating ARG nodes: an ARG with only 2 children (no default) appearing after hasOpt was set.
Common situations: Editing parameter lists and appending a new required param at the end, or reordering parameters during refactors of a DF signature without re-checking defaults.
Related errors
- Duplicated argument name %s
- Failed to parse DF signature '%s'%s
- unknown parse failure
- Failed to parse Type signature '%s'%s
- batch size must be a positive integer
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/4224b6ddd1287951.
Report an issue: GitHub.