theonedev/onedev · error · ExplicitException

Unexpected criteria: ${operator}

Error message

Unexpected criteria: ${operator}

What it means

In visitOperatorValueCriteria, PackQuery maps operator-value criteria like 'published by <user>', 'published by build <n>', 'published by project <x>' to concrete Criteria classes. If the operator token matches none of the known patterns, it throws ExplicitException("Unexpected criteria: <operator>").

Source

Thrown at server-core/src/main/java/io/onedev/server/search/entity/pack/PackQuery.java:123

								return new PublishedByMeCriteria();
							default:
								throw new ExplicitException("Unexpected operator: " + ctx.operator.getText());
						}
					}

					@Override
					public Criteria<Pack> visitOperatorValueCriteria(PackQueryParser.OperatorValueCriteriaContext ctx) {
						var criterias = new ArrayList<Criteria<Pack>>();
						for (var quoted: ctx.criteriaValue.Quoted()) {
							String value = getValue(quoted.getText());
							if (ctx.PublishedByUser() != null)
								criterias.add(new PublishedByUserCriteria(getUser(value)));
							else if (ctx.PublishedByBuild() != null)
								criterias.add(new PublishedViaBuildCriteria(project, value));
							else if (ctx.PublishedByProject() != null)
								criterias.add(new PublishedViaProjectCriteria(value));
							else
								throw new ExplicitException("Unexpected criteria: " + ctx.operator.getText());
						}	
						return Criteria.orCriterias(criterias);
					}
					
					@Override
					public Criteria<Pack> visitFieldOperatorValueCriteria(FieldOperatorValueCriteriaContext ctx) {
						String fieldName = getValue(ctx.criteriaField.getText());
						int operator = ctx.operator.getType();
						checkField(project, fieldName, operator);

						var criterias = new ArrayList<Criteria<Pack>>();
						for (var quoted: ctx.criteriaValue.Quoted()) {
							String value = getValue(quoted.getText());
							switch (operator) {
								case IsUntil:
								case IsSince:
									if (fieldName.equals(NAME_PUBLISH_DATE))
										criterias.add(new PublishDateCriteria(value, operator));

View on GitHub (pinned to d44925c47c)

Solutions

  1. Use one of the supported forms: 'published by <user>', 'published by build <n>', 'published by project <name>'
  2. Validate the query in the UI editor before saving/calling the API
  3. Catch ExplicitException to report the offending operator to the user

Example fix

// before
"published by user john" // unsupported form
// after
"published by john"
Defensive patterns

Strategy: validation

Validate before calling

const valid = /^published by (build \d+|project \S+|\S+)$/i; q.split(/\b(?:and|or)\b/i).forEach(c => { if (/published by/i.test(c) && !valid.test(c.trim())) throw new Error('bad operator-value criterion: ' + c.trim()); });

Type guard

null

Try / catch

try { PackQuery.parse(project, q); } catch (ExplicitException e) { if (e.getMessage().startsWith('Unexpected criteria')) showError(e.getMessage()); else throw e; }

Prevention

When it happens

Trigger: A pack query operator-value criterion whose operator is not PublishedByUser, PublishedByBuild, or PublishedByProject — e.g. typo'd or unsupported operator with a value attached, or query text from a different grammar version.

Common situations: Typos like 'published by user john' vs 'published by john'; reusing issue/build query operators on pack queries; version drift between saved queries and current parser.

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/49f6f5e375958a3d. Report an issue: GitHub.