theonedev/onedev · error · RuntimeException

Malformed job match

Error message

Malformed job match

What it means

Thrown by JobMatch.parse when the ANTLR lexer/parser reports a syntax error while parsing a job match expression. Wrapped in a RuntimeException with the underlying RecognitionException attached, meaning the match string does not conform to the JobMatch grammar.

Source

Thrown at server-core/src/main/java/io/onedev/server/job/match/JobMatch.java:57

	
	public JobMatch(Criteria<JobMatchContext> criteria) {
		this.criteria = criteria;
	}

	public static String getValue(String token) {
		return StringUtils.unescape(FenceAware.unfence(token));
	}
	
	public static JobMatch parse(String jobMatchString, boolean withProjectCriteria, boolean withJobCriteria) {
		CharStream is = CharStreams.fromString(jobMatchString); 
		JobMatchLexer lexer = new JobMatchLexer(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 job match", e);
			}
			
		});
		CommonTokenStream tokens = new CommonTokenStream(lexer);
		JobMatchParser parser = new JobMatchParser(tokens);
		parser.removeErrorListeners();
		parser.setErrorHandler(new BailErrorStrategy());
		JobMatchParser.JobMatchContext JobMatchContext = parser.jobMatch();

		Criteria<io.onedev.server.job.match.JobMatchContext> criteria = new JobMatchBaseVisitor<Criteria<io.onedev.server.job.match.JobMatchContext>>() {

			@Override
			public Criteria<io.onedev.server.job.match.JobMatchContext> visitParensCriteria(JobMatchParser.ParensCriteriaContext ctx) {
				return visit(ctx.criteria()).withParens(true);
			}

			@Override
			public Criteria<io.onedev.server.job.match.JobMatchContext> visitFieldOperatorValueCriteria(JobMatchParser.FieldOperatorValueCriteriaContext ctx) {

View on GitHub (pinned to d44925c47c)

Solutions

  1. Validate the match expression syntax against OneDev's job match grammar
  2. Check for unbalanced parentheses, missing 'or'/'and' operators, and unquoted values
  3. Rewrite the expression incrementally, testing in the UI's expression editor if available
  4. See the server log's nested RecognitionException for the offending token/position

Example fix

// before
JobMatch.parse("branch is main &&", false, false); // trailing operator
// after
JobMatch.parse("branch is main", false, false);
Defensive patterns

Strategy: validation

Validate before calling

// validate expression syntax before use
try {
    JobMatch.parse(expression, false, false);
} catch (RuntimeException e) {
    throw new IllegalArgumentException("Invalid job match expression: " + expression, e);
}

Try / catch

try {
    var match = JobMatch.parse(expr, false, false);
} catch (RuntimeException e) {
    // surface syntax error with offending position from cause
}

Prevention

When it happens

Trigger: Parsing an authorization/condition expression with invalid syntax — unbalanced parentheses, unknown keywords, missing operators, stray characters — via JobMatch.parse(expression, withProjectCriteria, withJobCriteria).

Common situations: Typo in match expression in a secret authorization field or build condition; quoting mistakes around values; copied expressions using unsupported syntax from other CI systems.

Understand the failure class

Related errors


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