{"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/87876ca5c0569b4933aec2d30d6225e4b9ba3a43/src/main/java/tools/jackson/databind/deser/bean/CreatorCollector.java#L322-L355","documentation":"CreatorCollector found two creators of the same kind (two constructors, or two factories, etc.) competing for the same creator slot. Jackson allows at most one creator per category (default, delegating, property-based) unless mode is explicitly disambiguated; otherwise the conflict is reported.","triggerScenarios":"Multiple @JsonCreator constructors/factories on the same type; a constructor and a factory method both annotated @JsonCreator(Mode.PROPERTIES); two property-based constructors where neither is marked explicit and Jackson cannot pick; an implicit public constructor colliding with an explicitly annotated one in some configurations.","commonSituations":"Builder-style types with both a constructor and a static factory; refactor introducing a second creator without removing the first; third-party types with multiple constructors; Kotlin data classes plus an extra @JsonCreator.","solutions":["Keep exactly one @JsonCreator per mode; remove redundant annotations or mark one @JsonCreator(Mode.DISABLED).","If two creators are needed, disambiguate with explicit Mode (Mode.DELEGATING vs Mode.PROPERTIES) so each occupies a different slot.","For builder types, annotate the builder constructor/factory and let the build() method be discovered separately.","Add @JsonCreator on the canonical constructor only and let Jackson auto-detect the others as regular."],"exampleFix":"// before\npublic class Foo {\n    @JsonCreator public Foo(int x) {}\n    @JsonCreator public static Foo of(int x) { return new Foo(x); } // conflict\n}\n\n// after\npublic class Foo {\n    @JsonCreator(Mode.DELEGATING) public Foo(int x) {}\n    @JsonCreator(Mode.PROPERTIES) public static Foo of(@JsonProperty(\"x\") int x) { return new Foo(x); }\n}","handlingStrategy":"validation","validationCode":"List<AnnotatedWithParams> props = collectPropertyCreators(type);\nif (props.size() > 1) {\n    throw new IllegalStateException(\"Multiple property creators on \" + type);\n}","typeGuard":"// no type guard; creator-conflict is runtime introspection","tryCatchPattern":"try { mapper.readValue(json, Foo.class); }\ncatch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Conflicting\")) {\n        // disambiguate with @JsonCreator(Mode.X) or remove one creator\n    } else throw e;\n}","preventionTips":["Keep exactly one @JsonCreator per Mode on a type.","For builders, annotate only the factory and let build() be discovered separately."],"tags":["deserialization","creator","constructor","conflict"],"backgroundTag":null,"analyzedSha":"87876ca5c0569b4933aec2d30d6225e4b9ba3a43","analyzedAt":"2026-08-11T12:55:24.033Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}