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

  1. Verify the property exists in the map (findDefinition(name) != null) before calling replace.
  2. Ensure replace is called at most once per property instance during construction.
  3. If you are subclassing BeanDeserializerFactory, perform replaces in the correct phase (post-resolve, post-remove).
  4. 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

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


AI-assisted analysis of FasterXML/jackson-databind@87876ca5c0 (2026-08-11). Data as JSON: /api/errors/ba540a7fc6999580. Report an issue: GitHub.