theonedev/onedev · error · RuntimeException
Malformed action condition
Error message
Malformed action condition
What it means
Thrown by ActionCondition.syntaxError listener when the ANTLR lexer/parser fails to parse an action condition expression. It is a plain RuntimeException wrapping the ANTLR RecognitionException, meaning the condition text does not conform to the action condition grammar.
Source
Thrown at server-core/src/main/java/io/onedev/server/buildspec/job/action/condition/ActionCondition.java:82
public static String getValue(String token) {
return StringUtils.unescape(FenceAware.unfence(token));
}
@Override
public boolean matches(Build build) {
return criteria.matches(build);
}
public static ActionCondition parse(Job job, String conditionString) {
CharStream is = CharStreams.fromString(conditionString);
ActionConditionLexer lexer = new ActionConditionLexer(is);
lexer.removeErrorListeners();
lexer.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,
int charPositionInLine, String msg, RecognitionException e) {
throw new RuntimeException("Malformed action condition", e);
}
});
CommonTokenStream tokens = new CommonTokenStream(lexer);
ActionConditionParser parser = new ActionConditionParser(tokens);
parser.removeErrorListeners();
parser.setErrorHandler(new BailErrorStrategy());
ConditionContext conditionContext = parser.condition();
Criteria<Build> criteria;
if (conditionContext.Always() != null) {
criteria = new AlwaysCriteria();
} else {
criteria = new ActionConditionBaseVisitor<Criteria<Build>>() {
@Override
public Criteria<Build> visitParensCriteria(ParensCriteriaContext ctx) {View on GitHub (pinned to d44925c47c)
Solutions
- Read the wrapped RecognitionException (the 'Caused by' chain) for line/char position and offending symbol.
- Fix quoting: wrap string values in single quotes and escape embedded quotes.
- Verify parentheses are balanced and operators are spelled exactly as the grammar expects (e.g. previous build state names, field operator names).
- Use the condition builder/editor UI in OneDev instead of hand-writing the expression.
Example fix
// before condition: this succeeded || previous build failed // after (grammar-compliant syntax) condition: this build is successful and previous build is failed
Defensive patterns
Strategy: try-catch
Validate before calling
// no public pre-parse validator; dry-run parse yourself
try {
ActionCondition.parse(conditionText, job, build);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Malformed action condition")) {
// reject/repair conditionText before real use
} else throw e;
} Try / catch
try {
ActionCondition.parse(text, job, build);
} catch (RuntimeException e) {
throw new IllegalArgumentException("Invalid condition '" + text + "': " + e.getMessage(), e);
} Prevention
- Validate condition strings with a dry parse in CI before shipping the buildspec.
- Avoid hand-typing operators; copy from documented examples.
- Beware smart quotes when pasting from rich-text editors.
When it happens
Trigger: Passing a syntactically invalid condition string to ActionCondition.parse — e.g. unbalanced quotes or parentheses, unknown tokens, misspelled operator keywords, or dangling expressions.
Common situations: Hand-editing the job condition in buildspec.yml; copying conditions from docs with wrong quoting; using an operator name not in the grammar; smart quotes from copy-pasting from editors.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unexpected operator:
- Param not found:
- Malformed log instruction
- Malformed retry condition
- Malformed build spec (import project: {0}, import revision:
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/aad3d1bb3b8339d5.
Report an issue: GitHub.