theonedev/onedev · error · ExplicitException
Property 'type' is reserved (class: X)
Error message
Property 'type' is reserved (class: X)
What it means
In generated JSON schemas, the 'type' property name is reserved for polymorphic type discrimination. processBean iterates a bean's properties and throws this ExplicitException if any property is literally named 'type', since it would clash with the discriminator.
Source
Thrown at server-core/src/main/java/io/onedev/server/ai/BuildSpecSchema.java:221
lastValueBytes = SerializationUtils.serialize((Serializable) value);
valueBytesMap.put(property.getPropertyName(), lastValueBytes);
} else if (!Arrays.equals(lastValueBytes, SerializationUtils.serialize((Serializable) value))) {
excludedProperties.add(property.getPropertyName());
}
}
}
}
}
if (bean == null) {
bean = newBean(beanClass);
}
var dependents = new ArrayList<Pair<PropertyDescriptor, DependsOn[]>>();
for (var groupProperties: beanDescriptor.getProperties().values()) {
for (var property: groupProperties) {
if (!excludedProperties.contains(property.getPropertyName()) && processedProperties.add(property.getPropertyName())) {
if (property.getPropertyName().equals("type"))
throw new ExplicitException("Property 'type' is reserved (class: " + beanClass.getName() + ")");
var dependsOns = property.getPropertyGetter().getAnnotationsByType(DependsOn.class);
if (dependsOns.length != 0) {
dependents.add(new Pair<>(property, dependsOns));
} else {
if (property.isPropertyRequired())
requiredNode.add(property.getPropertyName());
var propNode = new HashMap<String, Object>();
propsNode.put(property.getPropertyName(), propNode);
processProperty(propNode, bean, property);
}
}
}
}
if (!dependents.isEmpty()) {
var allOfNode = new ArrayList<Map<String, Object>>();
currentNode.put("allOf", allOfNode);
for (var dependent: dependents) {
var allOfItemNode = new HashMap<String, Object>();View on GitHub (pinned to d44925c47c)
Solutions
- Rename the property to something else (e.g. 'executorType', 'kind') in the bean class.
- If 'type' must appear in the output YAML, keep the Java property name different and add an @Property/description mapping as supported by the spec framework.
- Exclude the property from schema processing if your version exposes an exclusion mechanism (excludedProperties) for it.
Example fix
// before
private String type;
public String getType() { return type; }
// after
private String executorType;
public String getExecutorType() { return executorType; } Defensive patterns
Strategy: validation
Validate before calling
for (PropertyDescriptor p : beanProperties) {
if (p.getPropertyName().equals("type"))
throw new IllegalStateException("'type' is reserved: " + beanClass.getName());
} Try / catch
try {
schema = BuildSpecSchema.generate(specClass);
} catch (ExplicitException e) {
if (e.getMessage().contains("Property 'type' is reserved")) {
// rename the property in the class indicated by the message
}
} Prevention
- Avoid 'type' as a property name in spec beans.
- Reserve 'type' for the polymorphic discriminator only.
- Add unit tests generating schemas for all custom bean classes.
When it happens
Trigger: Defining a build spec bean class (processed via processType/processPolymorphic) that has a getter/property named 'type' which is not in the excludedProperties set, then generating the schema.
Common situations: Custom spec classes mirroring external YAML formats that use 'type' as a field name, or porting an existing config class into OneDev's build spec model without renaming the property.
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
- Unknown collection element class (bean: X, property: Y)
- 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/25ba7508b80ea414.
Report an issue: GitHub.