theonedev/onedev · error · RuntimeException

Malformed query

Error message

Malformed query

What it means

BuildMetricQuery.parse compiles a build metric query string with an ANTLR lexer/parser; when the lexer or parser hits a syntax error it throws a plain RuntimeException with message 'Malformed query' (RecognitionException as cause). The query string is not valid build metric query syntax.

Source

Thrown at server-core/src/main/java/io/onedev/server/search/buildmetric/BuildMetricQuery.java:45

	public BuildMetricQuery(@Nullable BuildMetricCriteria criteria) {
		this.criteria = criteria;
	}

	public BuildMetricQuery() {
		this(null);
	}
	
	public static BuildMetricQuery parse(Project project, @Nullable String queryString) {
		if (queryString != null) {
			CharStream is = CharStreams.fromString(queryString); 
			BuildMetricQueryLexer lexer = new BuildMetricQueryLexer(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 query", e);
				}
				
			});
			CommonTokenStream tokens = new CommonTokenStream(lexer);
			BuildMetricQueryParser parser = new BuildMetricQueryParser(tokens);
			parser.removeErrorListeners();
			parser.setErrorHandler(new BailErrorStrategy());
			QueryContext queryContext = parser.query();
			CriteriaContext criteriaContext = queryContext.criteria();
			BuildMetricCriteria metricCriteria;
			if (criteriaContext != null) {
				metricCriteria = new BuildMetricQueryBaseVisitor<BuildMetricCriteria>() {

					@Override
					public BuildMetricCriteria visitOperatorCriteria(OperatorCriteriaContext ctx) {
						switch (ctx.operator.getType()) {
						case BuildIsSuccessful:
							return new BuildIsSuccessfulCriteria();

View on GitHub (pinned to d44925c47c)

Solutions

  1. Inspect the cause (RecognitionException / ANTLR msg in the stack trace) to find the offending line and character position.
  2. Correct the query syntax: balance parentheses, use supported operators (e.g. BuildIsSuccessful, BuildIsFailed) and valid literal values.
  3. Build the query incrementally, validating a minimal expression first and adding clauses one at a time.
  4. If constructed programmatically, use the criteria objects (BuildIsSuccessfulCriteria etc.) instead of string concatenation to guarantee valid syntax.

Example fix

// before
String query = "status is successful AND (failed"; // unbalanced parens
BuildMetricQuery.parse(query);
// after
String query = "status is successful";
BuildMetricQuery.parse(query); // parses cleanly
Defensive patterns

Strategy: try-catch

Validate before calling

try {
    BuildMetricQuery.parse(query);
    return true;
} catch (RuntimeException e) {
    return false; // invalid metric query syntax
}

Type guard

boolean isValidMetricQuery(String q) {
    if (q == null || q.isBlank()) return false;
    int depth = 0;
    for (char c : q.toCharArray()) {
        if (c == '(') depth++; else if (c == ')') depth--;
        if (depth < 0) return false;
    }
    return depth == 0; // cheap pre-check; full check via parse()
}

Try / catch

try {
    BuildMetricQuery query = BuildMetricQuery.parse(userInput);
    // use query
} catch (RuntimeException e) {
    throw new ExplicitException("Invalid build metric query: " + e.getCause().getMessage());
}

Prevention

When it happens

Trigger: Passing a syntactically invalid query to the build metric query parser, e.g. unbalanced parentheses, missing operands around operators, invalid tokens, or unterminated strings in dashboard/report metric query fields.

Common situations: Users hand-typing metric queries in dashboards or REST calls; quoting mistakes around values with spaces; copying SQL-like syntax that the metric query grammar does not accept; localized characters the lexer rejects.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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