FasterXML/jackson-databind · error · NoSuchElementException
No entry '${oldProp.getName()}' found, can't replace
Error message
No entry '${oldProp.getName()}' found, can't replace What it means
BeanPropertyMap.replace requires the old property to actually be present in the in-order array; if it is not found (no reference equality match), it throws NoSuchElementException. This indicates the caller is trying to swap a property that was never inserted (or was already replaced/removed).
Source
Thrown at src/main/java/tools/jackson/databind/deser/bean/BeanPropertyMap.java:266
// 17-Nov-2017, tatu: do NOT try to change indexes since this could lead to discrepancies
// (unless we actually copy property instances)
return new BeanPropertyMap(newProps, newAliases, _locale, _caseInsensitive, false);
}
/**
* Specialized method that can be used to replace an existing entry
* (note: entry MUST exist; otherwise exception is thrown) with
* specified replacement.
*/
public void replace(SettableBeanProperty oldProp, SettableBeanProperty newProp)
{
for (int i = 0, end = _propsInOrder.length; i < end; ++i) {
if (_propsInOrder[i] == oldProp) {
_propsInOrder[i] = newProp;
return;
}
}
throw new NoSuchElementException("No entry '"+oldProp.getName()+"' found, can't replace");
}
/**
* Specialized method for removing specified existing entry.
* NOTE: entry MUST exist, otherwise an exception is thrown.
*/
public void remove(SettableBeanProperty propToRm)
{
final String key = propToRm.getName();
final int len = _propsInOrder.length;
ArrayList<SettableBeanProperty> props = new ArrayList<>(len);
// [databind#5884]: Must also update _aliasDefs to stay aligned with _propsInOrder
ArrayList<PropertyName[]> aliases = (_aliasDefs != null)
? new ArrayList<PropertyName[]>(len) : null;
boolean found = false;
for (int i = 0; i < len; ++i) {
if (!found && _propsInOrder[i].getName().equals(key)) {
found = true;View on GitHub (pinned to 87876ca5c0)
Solutions
- Verify the property exists in the map (findDefinition(name) != null) before calling replace.
- Ensure replace is called at most once per property instance during construction.
- If you are subclassing BeanDeserializerFactory, perform replaces in the correct phase (post-resolve, post-remove).
- Upgrade third-party modules that manipulate BeanPropertyMap; the contract requires the old entry be present.
Example fix
// before
map.replace(oldProp, newProp); // throws if oldProp not present
// after
if (map.findDefinition(oldProp.getName()) != null) {
map.replace(oldProp, newProp);
} Defensive patterns
Strategy: validation
Validate before calling
if (map.findDefinition(oldProp.getName()) == null) {
// not present; skip replace
return;
} Type guard
// no type guard; runtime membership check via findDefinition
Try / catch
try { map.replace(oldProp, newProp); }
catch (NoSuchElementException e) {
// oldProp was not in the map; rebuild the map from scratch instead
} Prevention
- Replace each property exactly once during construction.
- In custom factories, perform replaces after the map is fully populated and before any removes.
When it happens
Trigger: Custom BeanDeserializerFactory code calling replace() with a property instance that is not in the map; double-replace of the same property; replace after remove; a custom module manipulating BeanPropertyMap out of order.
Common situations: Third-party modules (afterburner, blacklist) that rewrite properties and call replace twice; mixin application that removes a property before a later replace; race-free ordering bugs where replace runs before the map is populated.
Related errors
- Property '${getName()}' already had index (${_propertyIndex}
- Can only call after BeanDeserializer has been resolved
- Cannot pass null property name
- Missing constructor (broken JDK (de)serialization?)
- Should not call set() on ObjectIdProperty that has no Settab
AI-assisted analysis of FasterXML/jackson-databind@87876ca5c0 (2026-08-11).
Data as JSON: /api/errors/ba540a7fc6999580.
Report an issue: GitHub.