{"record":{"id":"a55b201d7d2535d6","repo":"FasterXML/jackson-databind","slug":"class-getclass-getname-does-not-override-w","errorCode":null,"errorMessage":"Class ${getClass().getName()} does not override `withBeanProperties()`, needs to","messagePattern":"Class (.+?) does not override `withBeanProperties\\(\\)`, needs to","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"src/main/java/tools/jackson/databind/deser/bean/BeanDeserializerBase.java","lineNumber":491,"sourceCode":"        _serializationShape = src._serializationShape;\n\n        _vanillaProcessing = src._vanillaProcessing;\n\n        _externalTypeIdHandler = src._externalTypeIdHandler;\n    }\n\n    public abstract BeanDeserializerBase withObjectIdReader(ObjectIdReader oir);\n\n    public abstract BeanDeserializerBase withByNameInclusion(Set<String> ignorableProps, Set<String> includableProps);\n\n    public abstract BeanDeserializerBase withIgnoreAllUnknown(boolean ignoreUnknown);\n\n    /**\n     * Mutant factory method that custom sub-classes must override; not left as\n     * abstract to prevent more drastic backwards compatibility problems.\n     */\n    public BeanDeserializerBase withBeanProperties(BeanPropertyMap props) {\n        throw new UnsupportedOperationException(\"Class \"+getClass().getName()\n                +\" does not override `withBeanProperties()`, needs to\");\n    }\n\n    @Override\n    public abstract ValueDeserializer<Object> unwrappingDeserializer(DeserializationContext ctxt,\n            NameTransformer unwrapper);\n\n    /**\n     * Fluent factory for creating a variant that can handle\n     * POJO output as a JSON Array. Implementations may ignore this request\n     * if no such input is possible.\n     */\n    protected abstract BeanDeserializerBase asArrayDeserializer();\n\n    // @since 3.0\n    protected abstract void initNameMatcher(DeserializationContext ctxt);\n\n    /*","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/FasterXML/jackson-databind/blob/87876ca5c0569b4933aec2d30d6225e4b9ba3a43/src/main/java/tools/jackson/databind/deser/bean/BeanDeserializerBase.java#L473-L509","documentation":"BeanDeserializerBase.withBeanProperties is a mutant factory that concrete BeanDeserializer subclasses must override; the base throws if not overridden. The base implementation exists only for backwards compatibility with subclasses that predate the method, so calling it on a subclass that did not override it is a contract violation.","triggerScenarios":"A third-party or custom BeanDeserializer subclass that extends BeanDeserializerBase but does not override withBeanProperties, being used with a code path that mutates the bean property map (e.g. ignoreUnknown, name-based inclusion filters applied post-construction).","commonSituations":"Upgrading Jackson to a version that added withBeanProperties and finding an old custom BeanDeserializer subclass no longer cooperates; using a third-party module whose deserializer subclass is out of date; code that calls withBeanProperties directly via reflection/generics.","solutions":["If you subclass BeanDeserializerBase, override withBeanProperties to reconstruct the deserializer with the new BeanPropertyMap.","Upgrade the third-party module that ships the subclass so it overrides withBeanProperties.","Avoid the code path that triggers the mutation (e.g. do not apply withByNameInclusion after construction on the uncooperative subclass)."],"exampleFix":"// before\npublic class MyBeanDeserializer extends BeanDeserializerBase {\n    // missing withBeanProperties override -> throws when mutated\n}\n\n// after\npublic class MyBeanDeserializer extends BeanDeserializerBase {\n    @Override\n    public BeanDeserializerBase withBeanProperties(BeanPropertyMap props) {\n        // reconstruct using the copy constructor that accepts the new props\n        return new MyBeanDeserializer(this, props);\n    }\n}","handlingStrategy":"type-guard","validationCode":"BeanDeserializerBase d = ...;\nif (d.getClass().getMethod(\"withBeanProperties\", BeanPropertyMap.class)\n        .getDeclaringClass() == BeanDeserializerBase.class) {\n    // not overridden; do not call withBeanProperties\n}","typeGuard":"static boolean overridesWithBeanProperties(BeanDeserializerBase d) {\n    try {\n        return d.getClass().getMethod(\"withBeanProperties\", BeanPropertyMap.class)\n                   .getDeclaringClass() != BeanDeserializerBase.class;\n    } catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try { d.withBeanProperties(props); }\ncatch (UnsupportedOperationException e) {\n    // subclass needs to override withBeanProperties; upgrade it\n}","preventionTips":["When subclassing BeanDeserializerBase, override every mutant factory the base declares.","Keep third-party deserializer modules version-aligned with the Jackson in use."],"tags":["deserialization","bean-deserializer","subclassing","contract-violation"],"backgroundTag":null,"analyzedSha":"87876ca5c0569b4933aec2d30d6225e4b9ba3a43","analyzedAt":"2026-08-11T12:55:24.033Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}