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;
            else

View on GitHub (pinned to d44925c47c)

Solutions

  1. Add an explicit generic type parameter to the collection getter, e.g. List<String> instead of raw List.
  2. If the element type is a custom class, ensure the getter's generic return type is concrete (not a type variable).
  3. 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

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


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