halo-dev/halo · error · IllegalArgumentException
No value present for label key: {}
Error message
No value present for label key: {} What it means
Thrown by FieldSelectorConverter.getSingleValue when an Equals or NotEquals SelectorCriteria has an empty/null values collection. Equals and NotEquals require exactly one value to build an equality query; with no value the converter cannot form the condition and throws, naming criteria.key().
Source
Thrown at api/src/main/java/run/halo/app/extension/router/selector/FieldSelectorConverter.java:38
switch (criteria.operator()) {
case Equals -> {
return Queries.equal(key, getSingleValue(criteria));
}
case NotEquals -> {
return Queries.notEqual(key, getSingleValue(criteria));
}
// compatible with old field selector
case IN -> {
Set<String> valueArr = defaultIfNull(criteria.values(), Set.of());
return Queries.in(key, valueArr);
}
default -> throw new IllegalArgumentException("Unsupported operator: " + criteria.operator());
}
}
String getSingleValue(SelectorCriteria criteria) {
if (CollectionUtils.isEmpty(criteria.values())) {
throw new IllegalArgumentException("No value present for label key: " + criteria.key());
}
return criteria.values().iterator().next();
}
}
View on GitHub (pinned to d2f5165f9c)
Solutions
- When constructing SelectorCriteria for Equals/NotEquals, always pass a non-empty Set with exactly one value.
- Prefer the Operator.convert(String) parser for user input, which guarantees a value for '='/'!='.
- Guard programmatically: assert criteria.values() is non-empty before invoking the converter for value operators.
Example fix
// before
new SelectorCriteria("status", Operator.Equals, Set.of());
// after
new SelectorCriteria("status", Operator.Equals, Set.of("active")); Defensive patterns
Strategy: validation
Validate before calling
if ((criteria.operator() == Operator.Equals || criteria.operator() == Operator.NotEquals)
&& CollectionUtils.isEmpty(criteria.values())) {
throw new IllegalArgumentException("Operator " + criteria.operator()
+ " requires a value for key " + criteria.key());
} Type guard
boolean hasValue = !CollectionUtils.isEmpty(criteria.values());
Try / catch
try {
String value = converter.getSingleValue(criteria);
} catch (IllegalArgumentException e) {
// supply a default or reject the malformed selector
} Prevention
- Build SelectorCriteria via Operator.convert(String) so value operators always carry a value.
- When constructing manually, always pass a single-element Set for Equals/NotEquals.
- Unit-test selector construction to assert non-empty values for value operators.
When it happens
Trigger: A SelectorCriteria with operator Equals/NotEquals but values() empty or null reaches getSingleValue — typically only possible when building SelectorCriteria programmatically (the standard Operator parser rejects key= with an empty trailing value, so this guards internal/SDK construction).
Common situations: An SDK or extension builds SelectorCriteria manually and forgets to populate values; a mapping layer drops the value; an edge-case input that bypasses Operator.convert.
Related errors
- Unsupported operator: {}
- No value present for label key: {}
- Unsupported operator: {}
- No such thumbnail size: {}
- Unexpected APIVersion string: {}
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/4bf8d7a9259bee3c.
Report an issue: GitHub.