theonedev/onedev · error · ExplicitException

Unexpected operator

Error message

Unexpected operator 

What it means

Inside visitFieldOperatorValueCriteria, when the parser reduces multiple values of a field-operator-value criteria (e.g. "State is x or y"), it maps each operator to a criteria type; Is/IsNot and IsBefore/IsAfter are the only operators handled. Any other operator reaching this switch (an internal grammar/parser mismatch) throws this ExplicitException including the grammar rule name of the unexpected operator. Unlike the 'not supported here' errors, this usually indicates a bug or a field/operator combination the switch does not cover rather than a user mistake.

Source

Thrown at server-core/src/main/java/io/onedev/server/search/entity/issue/IssueQuery.java:492

												criterias.add(new IntegerFieldCriteria(fieldName, getIntValue(value), operator));
											} else if (field instanceof FloatField) {
												criterias.add(new FloatFieldCriteria(fieldName, getFloatValue(value), operator));
											} else {
												long ordinal;
												if (validate)
													ordinal = getValueOrdinal((ChoiceField) field, value);
												else
													ordinal = 0;
												criterias.add(new ChoiceFieldCriteria(fieldName, value, ordinal, operator, false));
											}
									}
									break;
								case IsBefore:
								case IsAfter:
									criterias.add(new StateCriteria(value, operator));
									break;
								default:
									throw new ExplicitException("Unexpected operator " + getRuleName(operator));
							}
						}
						return operator==IsNot? Criteria.andCriterias(criterias): Criteria.orCriterias(criterias);
					}

					@Override
					public Criteria<Issue> visitOrCriteria(OrCriteriaContext ctx) {
						List<Criteria<Issue>> childCriterias = new ArrayList<>();
						for (CriteriaContext childCtx : ctx.criteria())
							childCriterias.add(visit(childCtx));
						return new OrCriteria<>(childCriterias);
					}

					@Override
					public Criteria<Issue> visitAndCriteria(AndCriteriaContext ctx) {
						List<Criteria<Issue>> childCriterias = new ArrayList<>();
						for (CriteriaContext childCtx : ctx.criteria())
							childCriterias.add(visit(childCtx));

View on GitHub (pinned to d44925c47c)

Solutions

  1. Rewrite the query to use only "is"/"is not" (or is before/is after for state values) with multiple values, e.g. "State is Open, Closed".
  2. Report/fix the parser switch in IssueQuery.visitFieldOperatorValueCriteria to handle the operator for that field.
  3. Catch ExplicitException around IssueQuery.parse and log the operator rule name to diagnose which operator slipped through.

Example fix

// before
IssueQuery.parse(project, "State is not before Open", option, true); // unsupported combo
// after
IssueQuery.parse(project, "State is not Open", option, true);
Defensive patterns

Strategy: try-catch

Validate before calling

// restrict multi-value field criteria to supported operators
Set<String> supported = Set.of("is", "is not", "is before", "is after");
// pre-scan query tokens; reject other operators combined with value lists

Try / catch

try {
    IssueQuery.parse(project, queryString, option, true);
} catch (ExplicitException e) {
    if (e.getMessage().startsWith("Unexpected operator"))
        log.error("Parser switch gap in visitFieldOperatorValueCriteria: {}", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: Parsing a multi-value field criteria like "<field> is/is not/is before/is after v1, v2" where the operator token falls through to the default branch, i.e. an operator other than Is/IsNot/IsBefore/IsAfter reaches this code path.

Common situations: A custom/modified grammar or new operator added to IssueQuery.g4 without updating this switch; unexpected operator tokens produced by unusual query syntax; version skew where a saved query uses an operator the local parser switch doesn't map.

Related errors


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