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
- 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".
- Report/fix the parser switch in IssueQuery.visitFieldOperatorValueCriteria to handle the operator for that field.
- 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
- Use only is/is not (and is before/is after for dates/states) with multi-value criteria
- Keep the grammar switch in visitFieldOperatorValueCriteria in sync with IssueQuery.g4 operators
- Log the getRuleName(operator) output when reproducing to identify the offending operator
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
- Unexpected operator:
- No issue in query context
- Please login to perform this query
- No current pull request in query context
- No current commit in query context
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/997b00a917dbe41e.
Report an issue: GitHub.