theonedev/onedev · error · RuntimeException

Malformed retry condition

Error message

Malformed retry condition

What it means

Thrown by RetryCondition's ANTLR syntaxError listener when a retry condition string fails to parse against the retry condition grammar. It wraps the ANTLR RecognitionException in a RuntimeException, so the cause chain contains position and offending-symbol details.

Source

Thrown at server-core/src/main/java/io/onedev/server/buildspec/job/retrycondition/RetryCondition.java:78

	@Override
	public Predicate getPredicate(@Nullable ProjectScope projectScope, CriteriaQuery<?> query, From<RetryContext, RetryContext> from, CriteriaBuilder builder) {
		throw new UnsupportedOperationException();
	}
	
	public boolean matches(RetryContext context) {
		return criteria.matches(context);
	}
	
	public static RetryCondition parse(Job job, String conditionString) {
		CharStream is = CharStreams.fromString(conditionString); 
		RetryConditionLexer lexer = new RetryConditionLexer(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 retry condition", e);
			}
			
		});
		CommonTokenStream tokens = new CommonTokenStream(lexer);
		RetryConditionParser parser = new RetryConditionParser(tokens);
		parser.removeErrorListeners();
		parser.setErrorHandler(new BailErrorStrategy());
		ConditionContext conditionContext = parser.condition();

		Criteria<RetryContext> criteria;
		
		if (conditionContext.Never() != null) {
			criteria = new NeverCriteria();
		} else {
			criteria = new RetryConditionBaseVisitor<Criteria<RetryContext>>() {
	
				@Override
				public Criteria<RetryContext> visitParensCriteria(ParensCriteriaContext ctx) {

View on GitHub (pinned to d44925c47c)

Solutions

  1. Inspect the Caused-by RecognitionException for line/char and offending token.
  2. Fix quoting and keyword spelling per the retry condition grammar.
  3. Simplify the condition and rebuild it incrementally, testing after each addition.

Example fix

// before
retry condition: error message contains 'connection reset'

// after (valid quoting/syntax)
retry condition: error message contains 'connection reset' && attempt < 3
Defensive patterns

Strategy: try-catch

Validate before calling

try {
    RetryCondition.parse(conditionText);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().contains("Malformed retry condition")) {
        // surface RecognitionException details (line/char) for the author
    } else throw e;
}

Try / catch

try {
    RetryCondition.parse(text);
} catch (RuntimeException e) {
    Throwable cause = e.getCause();
    throw new IllegalArgumentException("Invalid retry condition '" + text + "': " + (cause != null ? cause.getMessage() : e.getMessage()), e);
}

Prevention

When it happens

Trigger: A retry condition expression in the job spec with invalid syntax — misspelled keywords, unbalanced quotes, or tokens not in the grammar (e.g. bad operator names for 'error message'/'failure reason' criteria).

Common situations: Hand-writing retry conditions in buildspec.yml; quoting mistakes around error-message patterns; copy-paste artifacts like smart quotes.

Understand the failure class

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/7f7db2b11e68baa2. Report an issue: GitHub.