FasterXML/jackson-databind · error · IllegalArgumentException
Duplicate creator property
Error message
Duplicate creator property "%s" (index %s vs %d) for type %s
What it means
CreatorCollector detects that two parameters of a single property-based creator (constructor or @JsonCreator factory) share the same JSON name. Each creator parameter must map to a unique incoming property name; a duplicate makes deserialization ambiguous so construction is rejected.
Solutions
- Give each creator parameter a distinct @JsonProperty value (or let it derive from the parameter name with -parameters compilation).
- Annotate injectable parameters with @JacksonInject and ensure their names do not collide (empty-named injectables are skipped).
- If merging two parameters, use @JsonUnwrapped or a nested type instead of duplicating the name.
- Recompile with -parameters so Jackson can use the actual parameter names and remove redundant @JsonProperty.
Example fix
// before
@JsonCreator
public Foo(@JsonProperty("x") int a, @JsonProperty("x") int b) {} // duplicate
// after
@JsonCreator
public Foo(@JsonProperty("x") int a, @JsonProperty("y") int b) {} Defensive patterns
Strategy: validation
Validate before calling
Set<String> seen = new HashSet<>();
for (Parameter p : constructor.getParameters()) {
String n = jsonNameOf(p);
if (n != null && !n.isEmpty() && !seen.add(n)) {
throw new IllegalStateException("Duplicate creator property: " + n);
}
} Type guard
// no type guard; duplicate-name check is runtime
Try / catch
try { mapper.readValue(json, Foo.class); }
catch (IllegalArgumentException e) {
if (e.getMessage().contains("Duplicate creator property")) {
// rename one of the conflicting @JsonProperty parameters
} else throw e;
} Prevention
- Compile with -parameters and rely on actual names; annotate only when overriding.
- Annotate @JacksonInject parameters distinctly so they are skipped during the duplicate check.
When it happens
Trigger: A @JsonCreator constructor/factory with two parameters both annotated @JsonProperty("sameName"); two parameters whose names deduce to the same string; an injectable (@Inject) and a real parameter colliding after name resolution.
Common situations: Copy-paste of @JsonProperty names across parameters; kotlin/scala compiler-generated constructors that produce duplicate names; mixing @JsonProperty with @JacksonInject where the injectable lacks a distinct name; refactors that rename parameters but not the @JsonProperty values.
Related errors
- Conflicting creators: already had creator , encountered…
- Cannot call createParameterObject() on
- Property ' ' already had index ( ), trying to assign
- AnnotationIntrospector returned `Class<
- AnnotationIntrospector returned Class
AI-assisted analysis of FasterXML/jackson-databind@87876ca5c0 (2026-08-11).
Data as JSON: /api/errors/e6f4a127e5c4f57f.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/tools/jackson/databind/deser/bean/CreatorCollector.java:182
public void addPropertyCreator(AnnotatedWithParams creator,
boolean explicit, SettableBeanProperty[] properties)
{
if (verifyNonDup(creator, C_PROPS, explicit)) {
// Better ensure we have no duplicate names either...
if (properties.length > 1) {
HashMap<String, Integer> names = new HashMap<>();
for (int i = 0, len = properties.length; i < len; ++i) {
String name = properties[i].getName();
// Need to consider Injectables, which may not have
// a name at all, and need to be skipped
// (same for possible AnySetter)
if (name.isEmpty() && (properties[i].getInjectableValueId() != null)) {
continue;
}
Integer old = names.put(name, Integer.valueOf(i));
if (old != null) {
throw new IllegalArgumentException("Duplicate creator property \"%s\" (index %s vs %d) for type %s ".formatted(
name, old, i, ClassUtil.nameOf(_beanType.getRawClass())));
}
}
}
_propertyBasedArgs = properties;
}
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
public boolean hasDefaultCreator() {
return _creators[C_DEFAULT] != null;
}
View on GitHub (pinned to 87876ca5c0)