{"record":{"id":"581c18448ba46813","repo":"FasterXML/jackson-databind","slug":"class-does-not-override-withbeanproperties","errorCode":null,"errorMessage":"Class {} 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/a50c7d2a1d57234ac4adf70dbd88ac90db6436e4/src/main/java/tools/jackson/databind/deser/bean/BeanDeserializerBase.java#L473-L509","documentation":"Thrown by the default BeanDeserializerBase.withBeanProperties() implementation, which is a non-abstract mutant-factory method that throws UnsupportedOperationException. Subclasses of BeanDeserializerBase are expected to override this to support property map replacement during deserialization pipeline setup. If a custom or framework subclass fails to override it, calling withBeanProperties throws with a message identifying the offending class.","triggerScenarios":"Subclassing BeanDeserializerBase (or BeanDeserializer) without overriding withBeanProperties(). The framework calls withBeanProperties during contextualization or when applying name-based filtering (e.g., @JsonIgnoreProperties at the property level).","commonSituations":"Writing a custom BeanDeserializer that extends BeanDeserializerBase but does not override all required mutant factory methods. Using a Jackson version where a new mutant-factory method was added but a custom subclass was not updated. Third-party Jackson extensions that extend the base class.","solutions":["Override withBeanProperties(BeanPropertyMap props) in your custom BeanDeserializerBase subclass to return a new instance with the updated property map.","If extending BeanDeserializer, check which mutant factory methods it overrides and mirror that pattern.","Avoid subclassing BeanDeserializerBase directly; extend BeanDeserializer instead to inherit more overridden methods.","After a Jackson upgrade, check the base class for newly added mutant-factory methods and override them."],"exampleFix":"// before\npublic class CustomDeserializer extends BeanDeserializerBase {\n    // missing withBeanProperties override\n}\n// after\npublic class CustomDeserializer extends BeanDeserializerBase {\n    @Override\n    public BeanDeserializerBase withBeanProperties(BeanPropertyMap props) {\n        return new CustomDeserializer(this, props);\n    }\n}","handlingStrategy":"validation","validationCode":"// At startup, verify custom deserializer overrides withBeanProperties\nBeanDeserializerBase custom = ...;\ntry {\n    custom.withBeanProperties(mockPropertyMap);\n} catch (UnsupportedOperationException e) {\n    throw new IllegalStateException(\"Custom deserializer missing withBeanProperties override\", e);\n}","typeGuard":"static boolean overridesWithBeanProperties(Class<?> deserClass) {\n    try {\n        return deserClass.getMethod(\"withBeanProperties\", BeanPropertyMap.class)\n            .getDeclaringClass() != BeanDeserializerBase.class;\n    } catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":null,"preventionTips":["When subclassing BeanDeserializerBase, override ALL mutant-factory methods.","Prefer extending BeanDeserializer over BeanDeserializerBase to inherit overrides.","After Jackson upgrades, review new abstract or throwing methods in the base class."],"tags":["jackson","deserialization","custom-deserializer","override-required","subclassing"],"analyzedSha":"a50c7d2a1d57234ac4adf70dbd88ac90db6436e4","analyzedAt":"2026-08-06T20:31:51.404Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}