theonedev/onedev · error · ExplicitException
Unknown collection element class (bean: X, property: Y)
Error message
Unknown collection element class (bean: X, property: Y)
What it means
BuildSpecSchema generates a JSON schema from build spec bean classes. When a property returns a Collection, the code uses reflection to determine the collection's element class; if the generic return type carries no resolvable element type, it throws this ExplicitException because the schema cannot be built.
Source
Thrown at server-core/src/main/java/io/onedev/server/ai/BuildSpecSchema.java:101
var grammar = IOUtils.toString(grammarStream, StandardCharsets.UTF_8);
descriptionSections.add("NOTE: If set, the value should conform with below ANTLR v4 grammar:\n\n" + grammar);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
} finally {
IOUtils.closeQuietly(grammarStream);
}
}
if (descriptionSections.size() != 0)
currentNode.put("description", StringUtils.join(descriptionSections, "\n\n"));
Class<?> elementClass = null;
if (Collection.class.isAssignableFrom(returnType)) {
elementClass = ReflectionUtils.getCollectionElementClass(property.getPropertyGetter().getGenericReturnType());
if (elementClass == null)
throw new ExplicitException("Unknown collection element class (bean: " + property.getBeanClass() + ", property: " + property.getPropertyName() + ")");
processCollectionProperty(currentNode, elementClass);
} else {
processType(currentNode, returnType);
}
Object defaultValue;
var value = property.getPropertyValue(bean);
if (value instanceof Integer) {
var intValue = (Integer) value;
if (intValue == 0)
defaultValue = null;
else
defaultValue = intValue;
} else if (value instanceof Long) {
var longValue = (Long) value;
if (longValue == 0)
defaultValue = null;
elseView on GitHub (pinned to d44925c47c)
Solutions
- Add an explicit generic type parameter to the collection getter, e.g. List<String> instead of raw List.
- If the element type is a custom class, ensure the getter's generic return type is concrete (not a type variable).
- If writing a third-party spec class, follow OneDev's build spec conventions where all collection properties are strongly typed.
Example fix
// before
public List getSteps() { return steps; }
// after
public List<Step> getSteps() { return steps; } Defensive patterns
Strategy: type-guard
Validate before calling
for (Method m : beanClass.getMethods()) {
Type t = m.getGenericReturnType();
if (Collection.class.isAssignableFrom(m.getReturnType())
&& !(t instanceof ParameterizedType))
throw new IllegalStateException("Collection property needs generic type: " + m);
} Type guard
function isTypedCollection(m) {
return Collection.class.isAssignableFrom(m.getReturnType())
&& m.getGenericReturnType() instanceof ParameterizedType;
} Try / catch
try {
schema = BuildSpecSchema.generate(specClass);
} catch (ExplicitException e) {
if (e.getMessage().startsWith("Unknown collection element class")) {
// fix the offending raw collection getter named in the message
}
} Prevention
- Never use raw collection types in build spec beans.
- Always parameterize List/Set/Map property getters.
- Run schema generation in tests for custom spec classes.
When it happens
Trigger: Processing a bean property whose getter returns a Collection (List/Set) with an unparameterized or non-resolvable generic type, so ReflectionUtils.getCollectionElementClass returns null and processProperty throws.
Common situations: Custom build spec property classes defining raw List or Set fields without a type parameter, or using wildcards/generics the reflection helper cannot resolve.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Property 'type' is reserved (class: X)
- Unsupported type: X
- Dependency property not found: X
- Malformed build spec
- Circular template usages (
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/1a0d53f96db293d2.
Report an issue: GitHub.