FasterXML/jackson-databind · error · UnsupportedOperationException
Should never call `set()` on setterless property ('${getName
Error message
Should never call `set()` on setterless property ('${getName()}') What it means
SetterlessProperty models a read-only Collection/Map property: deserialization works by calling the getter to obtain the existing collection and then populating it. The set() method is intentionally disabled because there is no setter to invoke; calling it is a programming error (the property was never meant to receive a value directly).
Source
Thrown at src/main/java/tools/jackson/databind/deser/impl/SetterlessProperty.java:149
// we get JSON null might be compatible. If so, implementation could be changed.
if (toModify == null) {
ctxt.reportBadDefinition(getType(), "Problem deserializing 'setterless' property '%s': get method returned null".formatted(
getName()));
}
_valueDeserializer.deserialize(p, ctxt, toModify);
}
@Override
public Object deserializeSetAndReturn(JsonParser p,
DeserializationContext ctxt, Object instance) throws JacksonException
{
deserializeAndSet(p, ctxt, instance);
return instance;
}
@Override
public final void set(DeserializationContext ctxt, Object instance, Object value) {
throw new UnsupportedOperationException("Should never call `set()` on setterless property ('"+getName()+"')");
}
@Override
public Object setAndReturn(DeserializationContext ctxt, Object instance, Object value)
{
set(ctxt, instance, value);
return instance;
}
}View on GitHub (pinned to 87876ca5c0)
Solutions
- Expose a setter or field for the property if direct assignment is required.
- If populating in place is intended, ensure the deserializer goes through deserializeAndSet (which calls the getter and modifies the returned collection), not set().
- Filter out SetterlessProperty instances from generic property-iteration code that calls set().
- Add @JsonIgnore to the getter or annotate the field appropriately to avoid the property being treated as settable.
Example fix
// before (framework code)
for (SettableBeanProperty p : props) {
p.set(ctxt, bean, value); // throws on setterless property
}
// after (skip setterless, or use deserializeAndSet)
for (SettableBeanProperty p : props) {
if (!(p instanceof SetterlessProperty)) {
p.set(ctxt, bean, value);
}
} Defensive patterns
Strategy: type-guard
Validate before calling
if (p instanceof SetterlessProperty) {
// do not call set(); use deserializeAndSet or skip
return;
} Type guard
static boolean isSettable(SettableBeanProperty p) {
return !(p instanceof SetterlessProperty);
} Try / catch
try { p.set(ctxt, bean, value); }
catch (UnsupportedOperationException e) {
if (e.getMessage().contains("setterless property")) {
// add a setter/field, or skip this property
} else throw e;
} Prevention
- In generic property-iteration code, skip SetterlessProperty instances when calling set().
- If a property must be directly assignable, expose a setter or annotate the field.
When it happens
Trigger: Custom code or framework logic that calls SettableBeanProperty.set() on every property indiscriminately, hitting a setterless one; a JSON payload that triggers a code path attempting to assign a new collection to a getter-only field; misuse through reflection.
Common situations: A property exposed only via a getter returning a pre-initialized collection (e.g. private final List<X> items = new ArrayList<>(); with getItems()); code that tries to set rather than modify; using @JsonProperty on a getter-only member with a framework expecting a setter.
Related errors
- Cannot call createParameterObject() on ${getClass().getName(
- Cannot call withValueDeserializer() on ${getClass().getName(
- AnnotationIntrospector returned Converter definition of type
- AnnotationIntrospector returned Class {}; expected Class<Con
- Invalid abstract type resolution from {} to {}: latter is no
AI-assisted analysis of FasterXML/jackson-databind@87876ca5c0 (2026-08-11).
Data as JSON: /api/errors/d67410134cfc343d.
Report an issue: GitHub.