{"record":{"id":"9f5f18c855a85c85","repo":"FasterXML/jackson-databind","slug":"cannot-call-withvaluedeserializer-on-getclass","errorCode":null,"errorMessage":"Cannot call withValueDeserializer() on ${getClass().getName()}","messagePattern":"Cannot call withValueDeserializer\\(\\) on (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"src/main/java/tools/jackson/databind/deser/SettableAnyProperty.java","lineNumber":526,"sourceCode":"        // Let's override since this is much simpler with JsonNodes\n        @Override\n        public Object deserialize(JsonParser p, DeserializationContext ctxt)\n            throws JacksonException\n        {\n            return _valueDeserializer.deserialize(p, ctxt);\n        }\n\n        @Override\n        protected void _set(DeserializationContext ctxt, Object instance, Object propName, Object value)\n            throws Exception\n        {\n            ((ObjectNode) instance).set((String) propName, (JsonNode) value);\n        }\n\n        // Should not get called but...\n        @Override\n        public SettableAnyProperty withValueDeserializer(ValueDeserializer<Object> deser) {\n            throw new UnsupportedOperationException(\"Cannot call withValueDeserializer() on \" + getClass().getName());\n        }\n\n        @Override\n        public int getParameterIndex() { return _parameterIndex; }\n\n        @Override\n        public Object createParameterObject() { return _nodeFactory.objectNode(); }\n    }\n}\n","sourceCodeStart":508,"sourceCodeEnd":536,"githubUrl":"https://github.com/FasterXML/jackson-databind/blob/87876ca5c0569b4933aec2d30d6225e4b9ba3a43/src/main/java/tools/jackson/databind/deser/SettableAnyProperty.java#L508-L536","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nfor (SettableBeanProperty p : props) {\n    prop = p.withValueDeserializer(wrapped); // throws on node variant\n}\n\n// after\nfor (SettableBeanProperty p : props) {\n    if (!(p instanceof SettableAnyProperty) || p.getClass().getSimpleName().startsWith(\"Method\")) {\n        prop = p.withValueDeserializer(wrapped);\n    }\n}","handlingStrategy":"type-guard","validationCode":"if (p.getClass().getName().contains(\"ObjectNode\")\n        || p instanceof SettableAnyProperty && p.getParameterIndex() >= 0\n            && p.getClass().getEnclosingClass() == ObjectNode.class) {\n    // skip; node variant does not accept withValueDeserializer\n}","typeGuard":"static boolean canReplaceDeserializer(SettableBeanProperty p) {\n    // the node-backed variant throws; only POJO any-setters accept replacement\n    return !(p.getClass().getName().toLowerCase().contains(\"node\"));\n}","tryCatchPattern":"try { p.withValueDeserializer(wrapped); }\ncatch (UnsupportedOperationException e) {\n    // skip this property; it is the fixed node variant\n}","preventionTips":["In generic property-rewriting loops, isinstance-check before calling withValueDeserializer.","Keep ObjectNode-target deserialization separate from POJO pipelines that rewire deserializers."],"tags":["deserialization","any-setter","tree-model","unsupported-operation"],"backgroundTag":null,"analyzedSha":"87876ca5c0569b4933aec2d30d6225e4b9ba3a43","analyzedAt":"2026-08-11T12:55:24.033Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}