{"record":{"id":"b443e2af3ba3a4bb","repo":"FasterXML/jackson-databind","slug":"invalid-object-id-definition-for-s-cannot-find-p","errorCode":null,"errorMessage":"Invalid Object Id definition for %s: cannot find property with name %s","messagePattern":"Invalid Object Id definition for (.+?): cannot find property with name (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/tools/jackson/databind/deser/BeanDeserializerFactory.java","lineNumber":424,"sourceCode":"        JavaType idType;\n        SettableBeanProperty idProp;\n        ObjectIdGenerator<?> gen;\n\n        ObjectIdResolver resolver = ctxt.objectIdResolverInstance(beanDescRef.getClassInfo(), objectIdInfo);\n\n        // Just one special case: Property-based generator is trickier\n        if (implClass == ObjectIdGenerators.PropertyGenerator.class) { // most special one, needs extra work\n            PropertyName propName = objectIdInfo.getPropertyName();\n            idProp = deserBuilder.findProperty(propName);\n            if (idProp == null) {\n                // [databind#4014]: For abstract types (interfaces, abstract classes),\n                // the builder may not have settable properties (no setter/field).\n                // Concrete subtype deserializers will set up their own ObjectIdReader,\n                // so we can safely skip it here for the abstract type.\n                if (beanDescRef.getType().isAbstract()) {\n                    return;\n                }\n                throw new IllegalArgumentException(\"Invalid Object Id definition for %s: cannot find property with name %s\".formatted(\n                        ClassUtil.getTypeDescription(beanDescRef.getType()),\n                        ClassUtil.name(propName)));\n            }\n            idType = idProp.getType();\n            gen = new PropertyBasedObjectIdGenerator(objectIdInfo.getScope());\n        } else {\n            JavaType type = ctxt.constructType(implClass);\n            idType = ctxt.getTypeFactory().findTypeParameters(type, ObjectIdGenerator.class)[0];\n            idProp = null;\n            gen = ctxt.objectIdGeneratorInstance(beanDescRef.getClassInfo(), objectIdInfo);\n        }\n        // also: unlike with value deserializers, let's just resolve one we need here\n        ValueDeserializer<?> deser = ctxt.findRootValueDeserializer(idType);\n        deserBuilder.setObjectIdReader(ObjectIdReader.construct(idType,\n                objectIdInfo.getPropertyName(), gen, deser, idProp, resolver));\n    }\n\n    @SuppressWarnings(\"unchecked\")","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/FasterXML/jackson-databind/blob/87876ca5c0569b4933aec2d30d6225e4b9ba3a43/src/main/java/tools/jackson/databind/deser/BeanDeserializerFactory.java#L406-L442","documentation":"Thrown by BeanDeserializerFactory when @JsonIdentityInfo uses ObjectIdGenerators.PropertyGenerator and the named property cannot be found among the bean's settable properties. With a property-based generator, the id must live in an existing, settable property on the bean; if no property matches the configured name, the Object Id definition is invalid.","triggerScenarios":"Annotating a type with @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property=\"id\") where no field/setter/creator parameter named 'id' exists on the bean (or it is ignored/not visible).","commonSituations":"Renaming or removing the id property after adding @JsonIdentityInfo; pointing the property to a getter-only (no setter/field) that is not a creator argument; visibility settings hiding the property; misspelling the property name.","solutions":["Ensure a settable property with the configured name exists (field, setter, or creator parameter) on the bean.","Correct the property= value in @JsonIdentityInfo to match an existing property name.","If the type is abstract and has no settable properties, note the factory skips this for abstract types (databind#4014); ensure concrete subtypes define the property.","Switch to a non-property generator (e.g., SequenceGenerator, UUIDGenerator) if you have no natural id property."],"exampleFix":"// before: 'id' property does not exist on the bean\n@JsonIdentityInfo(\n    generator=ObjectIdGenerators.PropertyGenerator.class,\n    property=\"id\")\nclass Node { String name; }\n\n// after: add the id property\nclass Node { @JsonProperty(\"id\") Long id; String name; }","handlingStrategy":"validation","validationCode":"JsonIdentityInfo ann = type.getAnnotation(JsonIdentityInfo.class);\nif (ann != null && ann.generator() == ObjectIdGenerators.PropertyGenerator.class) {\n    Set<String> names = beanProperties.stream().map(BeanPropertyDefinition::getName).collect(toSet());\n    if (!names.contains(ann.property())) {\n        throw new IllegalStateException(\"@JsonIdentityInfo property '\" + ann.property() + \"' not found on \" + type);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure the @JsonIdentityInfo property= names an existing settable property.","Update the property= value when renaming the id field.","For abstract types, ensure concrete subtypes define the id property.","Prefer UUID/Sequence generators when no natural id property exists."],"tags":["jackson","deserialization","objectid","jsonidentityinfo","annotation","bean"],"backgroundTag":null,"analyzedSha":"87876ca5c0569b4933aec2d30d6225e4b9ba3a43","analyzedAt":"2026-08-11T12:55:24.033Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}