{"record":{"id":"44e986e536b2f767","repo":"FasterXML/jackson-databind","slug":"conflicting-s-creators-already-had-s-creator-s","errorCode":null,"errorMessage":"Conflicting %s creators: already had %s creator %s, encountered another: %s","messagePattern":"Conflicting (.+?) creators: already had (.+?) creator (.+?), encountered another: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/tools/jackson/databind/deser/bean/CreatorCollector.java","lineNumber":340,"sourceCode":"                } else {\n                    // 02-May-2020, tatu: Should this only result in exception if both\n                    //   explicit? Doing so could lead to arbitrary choice between\n                    //   multiple implicit creators tho?\n                    _reportDuplicateCreator(typeIndex, explicit, oldOne, newOne);\n                }\n            }\n        }\n        if (explicit) {\n            _explicitCreators |= mask;\n        }\n        _creators[typeIndex] = _fixAccess(newOne);\n        return true;\n    }\n\n    // @since 2.12\n    protected void _reportDuplicateCreator(int typeIndex, boolean explicit,\n            AnnotatedWithParams oldOne, AnnotatedWithParams newOne) {\n        throw new IllegalArgumentException(\"Conflicting %s creators: already had %s creator %s, encountered another: %s\".formatted(\n                TYPE_DESCS[typeIndex],\n                explicit ? \"explicitly marked\"\n                        : \"implicitly discovered\",\n                oldOne, newOne));\n    }\n\n    /**\n     * Helper method for recognizing `Enum.valueOf()` factory method\n     */\n    protected boolean _isEnumValueOf(AnnotatedWithParams creator) {\n        return ClassUtil.isEnumType(creator.getDeclaringClass())\n                && \"valueOf\".equals(creator.getName());\n    }\n}\n","sourceCodeStart":322,"sourceCodeEnd":355,"githubUrl":"https://github.com/FasterXML/jackson-databind/blob/a50c7d2a1d57234ac4adf70dbd88ac90db6436e4/src/main/java/tools/jackson/databind/deser/bean/CreatorCollector.java#L322-L355","documentation":"Thrown by CreatorCollector._reportDuplicateCreator via verifyNonDup when two creator methods of the same category (e.g., two property-based creators, two delegate creators, two string-creators) are detected and cannot be disambiguated. The verifyNonDup logic tries to resolve conflicts based on explicitness and type specificity, but when both are equally explicit with the same parameter type, it reports a conflict. This is a bean-definition configuration problem.","triggerScenarios":"Two constructors/factory methods both annotated with @JsonCreator(Mode.PROPERTIES) or @JsonCreator(Mode.DELEGATING). Two factory methods with the same single-parameter type both marked as creators. A class where auto-detection finds two candidates of the same kind with equal precedence.","commonSituations":"Adding @JsonCreator to a second constructor when one already exists. Using @JsonCreator on both a constructor and a static factory method that take the same parameter type. Library updates that change creator visibility rules exposing a previously hidden conflict.","solutions":["Designate exactly one creator per category (property-based, delegate, string, int, etc.) — remove or re-annotate the duplicate.","If both are needed for different scenarios, use @JsonCreator with explicit Mode (PROPERTIES vs DELEGATING) to disambiguate.","Adjust MapperFeature visibility settings (e.g., INFER_CREATOR_MODE_FROM_CONSTRUCTOR_PROPERTIES) if the conflict is from auto-detection.","Annotate only the intended creator; let the other remain unannotated so it is not auto-detected."],"exampleFix":"// before\n@JsonCreator public Foo(String s) { ... }\n@JsonCreator public static Foo of(String s) { ... }\n// after: keep only one\n@JsonCreator public static Foo of(String s) { ... }","handlingStrategy":"validation","validationCode":"// Before deploying, check for multiple creators\nList<AnnotatedWithParams> creators = ...;\nMap<Integer, Long> byType = creators.stream()\n    .collect(Collectors.groupingBy(c -> categorize(c), Collectors.counting()));\nbyType.forEach((type, count) -> {\n    if (count > 1) throw new IllegalStateException(\"Multiple type-\" + type + \" creators\");\n});","typeGuard":null,"tryCatchPattern":"try {\n    mapper.readValue(json, MyClass.class);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Conflicting\")) {\n        // fix creator annotations — this is a bean definition error\n    }\n}","preventionTips":["Annotate only one constructor or factory method as @JsonCreator per category.","If multiple creators exist, use explicit Mode to disambiguate.","Run a quick deserialization smoke test at startup to catch creator conflicts early."],"tags":["jackson","deserialization","creator","ambiguous","bean-definition"],"analyzedSha":"a50c7d2a1d57234ac4adf70dbd88ac90db6436e4","analyzedAt":"2026-08-06T20:31:51.404Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}