FasterXML/jackson-databind · error · UnsupportedOperationException
Cannot call withValueDeserializer() on ${getClass().getName(
Error message
Cannot call withValueDeserializer() on ${getClass().getName()} What it means
The ObjectNode-backed SettableAnyProperty variant (used when deserializing directly into a tree ObjectNode) throws on withValueDeserializer() because the value deserializer is fixed by the node factory and cannot be swapped. Calling this mutant factory on the tree variant is a programming error.
Source
Thrown at src/main/java/tools/jackson/databind/deser/SettableAnyProperty.java:526
// Let's override since this is much simpler with JsonNodes
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt)
throws JacksonException
{
return _valueDeserializer.deserialize(p, ctxt);
}
@Override
protected void _set(DeserializationContext ctxt, Object instance, Object propName, Object value)
throws Exception
{
((ObjectNode) instance).set((String) propName, (JsonNode) value);
}
// Should not get called but...
@Override
public SettableAnyProperty withValueDeserializer(ValueDeserializer<Object> deser) {
throw new UnsupportedOperationException("Cannot call withValueDeserializer() on " + getClass().getName());
}
@Override
public int getParameterIndex() { return _parameterIndex; }
@Override
public Object createParameterObject() { return _nodeFactory.objectNode(); }
}
}
View on GitHub (pinned to 87876ca5c0)
Solutions
- Guard any generic withValueDeserializer() call with an instanceof check to skip the node-backed any-setter variant.
- Use a custom deserializer for the node content itself rather than trying to rewire the any-setter.
- Avoid mixing ObjectNode target deserialization with code that assumes POJO any-setter semantics.
Example fix
// before
for (SettableBeanProperty p : props) {
prop = p.withValueDeserializer(wrapped); // throws on node variant
}
// after
for (SettableBeanProperty p : props) {
if (!(p instanceof SettableAnyProperty) || p.getClass().getSimpleName().startsWith("Method")) {
prop = p.withValueDeserializer(wrapped);
}
} Defensive patterns
Strategy: type-guard
Validate before calling
if (p.getClass().getName().contains("ObjectNode")
|| p instanceof SettableAnyProperty && p.getParameterIndex() >= 0
&& p.getClass().getEnclosingClass() == ObjectNode.class) {
// skip; node variant does not accept withValueDeserializer
} Type guard
static boolean canReplaceDeserializer(SettableBeanProperty p) {
// the node-backed variant throws; only POJO any-setters accept replacement
return !(p.getClass().getName().toLowerCase().contains("node"));
} Try / catch
try { p.withValueDeserializer(wrapped); }
catch (UnsupportedOperationException e) {
// skip this property; it is the fixed node variant
} Prevention
- In generic property-rewriting loops, isinstance-check before calling withValueDeserializer.
- Keep ObjectNode-target deserialization separate from POJO pipelines that rewire deserializers.
When it happens
Trigger: Custom deserializer/framework code calling withValueDeserializer() on the any-setter that targets ObjectNode (the JsonNode any-setter); a generic pipeline that indiscriminately rewraps every SettableBeanProperty with a new deserializer.
Common situations: A framework that wraps all properties with a tracing/auditing deserializer and hits the node variant; mixing tree-model deserialization with POJO binding in the same processing pipeline; subclassing that calls super.withValueDeserializer() on the node variant.
Related errors
- Cannot call createParameterObject() on ${getClass().getName(
- _anySetter already set to non-null
- Trying to resolve a forward reference with id [${id.toString
- Should never call `set()` on setterless property ('${getName
- AnnotationIntrospector returned Converter definition of type
AI-assisted analysis of FasterXML/jackson-databind@87876ca5c0 (2026-08-11).
Data as JSON: /api/errors/9f5f18c855a85c85.
Report an issue: GitHub.