{"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/a50c7d2a1d57234ac4adf70dbd88ac90db6436e4/src/main/java/tools/jackson/databind/deser/BeanDeserializerFactory.java#L406-L442","documentation":"Thrown while wiring @JsonIdentityInfo with a PropertyGenerator: the generator is told to use a specific property name as the id, but no settable property with that name exists on the bean. Abstract types are exempt (they defer to concrete subtypes), but concrete beans must own the named property.","triggerScenarios":"@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = \"id\") on a concrete class that has no field/getter/setter named 'id', or where the name was misspelled/renamed/hidden.","commonSituations":"Renaming the id property without updating the annotation; copying @JsonIdentityInfo from another class with a different id field name; the property being filtered out by a view or visibility rule.","solutions":["Add a property (field/getter/setter) matching the name in @JsonIdentityInfo(property=...).","Correct the property name in the annotation to match an existing property.","If the type is meant to be abstract, mark it abstract so the check is deferred to the concrete subtype.","If property-based generation isn't required, switch to a different generator (SequenceGenerator, UUIDGenerator)."],"exampleFix":"// before\n@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = \"key\")\nclass Item { Long id; String name; } // no 'key' property -> throws\n// after\n@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = \"id\")\nclass Item { Long id; String name; }","handlingStrategy":"validation","validationCode":"String idProp = \"id\";\nif (Arrays.stream(Item.class.getDeclaredFields())\n        .noneMatch(f -> f.getName().equals(idProp))) {\n    throw new IllegalStateException(\"Item has no property '\" + idProp\n        + \"' referenced by @JsonIdentityInfo\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep @JsonIdentityInfo(property=...) in sync with the actual id field name.","Concrete classes must own the named property; abstract bases may defer to subtypes.","Add a smoke test that builds a mapper for each @JsonIdentityInfo-annotated type."],"tags":["object-id","jsonidentityinfo","deserialization","property"],"analyzedSha":"a50c7d2a1d57234ac4adf70dbd88ac90db6436e4","analyzedAt":"2026-08-06T20:31:51.404Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}