theonedev/onedev · error · ExplicitException
Property 'type' is reserved (class: <className>)
Error message
Property 'type' is reserved (class: <className>)
What it means
During YAML data migration, VersionedYamlDoc builds a property set from a class's @Editable getters and setters. A bean property named 'type' is disallowed because 'type' is used internally in the versioned YAML document format to record the class name. Any persistable class exposing a getter/setter pair named 'type' aborts the migration/deserialization with this ExplicitException.
Source
Thrown at server-core/src/main/java/io/onedev/server/data/migration/VersionedYamlDoc.java:232
}
}
};
representer.setDefaultFlowStyle(FlowStyle.BLOCK);
representer.setPropertyUtils(new PropertyUtils() {
@Override
protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bAccess) {
List<Property> properties = new ArrayList<>();
Map<String, Integer> orders = new HashMap<>();
if (type.getAnnotation(Editable.class) != null) {
for (Method getter: BeanUtils.findGetters(type)) {
Editable editable = getter.getAnnotation(Editable.class);
Method setter = BeanUtils.findSetter(getter);
if (editable != null && setter != null) {
String propertyName = BeanUtils.getPropertyName(getter);
if (propertyName.equals("type"))
throw new ExplicitException("Property 'type' is reserved (class: " + type.getName() + ")");
try {
properties.add(new MethodProperty(new PropertyDescriptor(propertyName, getter, setter)));
} catch (IntrospectionException e) {
throw new RuntimeException(e);
}
orders.put(propertyName, editable.order());
}
}
}
Collections.sort(properties, new Comparator<Property>() {
@Override
public int compare(Property o1, Property o2) {
return orders.get(o1.getName()) - orders.get(o2.getName());
}
});
return new LinkedHashSet<>(properties);View on GitHub (pinned to d44925c47c)
Solutions
- Rename the bean property from 'type' to something else (e.g. 'typeName' or 'itemType').
- If 'type' must not be persisted, remove it from the bean or drop the @Editable annotation / setter so it is excluded from the property set.
- If the field is required for new data, add a migration step converting old YAML docs that used 'type'.
- Check whether the bean is actually meant to participate in versioned YAML persistence; exclude it if not.
Example fix
// before
@Editable
public String getType() { return type; }
public void setType(String type) { this.type = type; }
// after
@Editable
public String getItemType() { return itemType; }
public void setItemType(String itemType) { this.itemType = itemType; } Defensive patterns
Strategy: validation
Validate before calling
for (Method getter : BeanUtils.findGetters(type)) {
if (BeanUtils.getPropertyName(getter).equals("type"))
throw new IllegalStateException(type.getName() + " must not define a bean property named 'type'");
} Type guard
boolean hasReservedTypeProperty(Class<?> type) {
return BeanUtils.findGetters(type).stream()
.anyMatch(g -> BeanUtils.getPropertyName(g).equals("type"));
} Try / catch
try {
doc.createPropertySet();
} catch (ExplicitException e) {
log.error("Bean violates versioned YAML constraints: " + e.getMessage());
throw new ConfigurationException(e.getMessage());
} Prevention
- Never name a persisted bean property 'type' in classes serialized with VersionedYamlDoc.
- Add a unit test that round-trips persistable classes through VersionedYamlDoc.
- Prefer names like itemType, typeName, kind for discriminator fields.
- Check for reserved property names when introducing new entities used in migrations.
When it happens
Trigger: Persisting (via versioned YAML) a class that has an @Editable getter named getType() with a matching setter; e.g. adding a field named 'type' to a data entity or migration DTO.
Common situations: Renaming an enum-like discriminator field to 'type' on a persisted entity; copying POJO patterns from other frameworks where 'type' is a natural field name; old migrations failing after a new field was introduced.
Related errors
- Unable to find version
- Malformed build spec
- Malformed build spec (import project: {0}, import revision:
- Unable to upgrade specified installation as database is not
- Unable to upgrade specified installation due to above error
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/19ed8f1a761cfc4c.
Report an issue: GitHub.