FasterXML/jackson-databind · error · IllegalArgumentException

Cannot pass null resolver

Error message

Cannot pass null resolver

What it means

Thrown by DeserializerFactoryConfig.withValueInstantiators(ValueInstantiators) when the argument is null. ValueInstantiators hooks provide custom ValueInstantiator instances used to construct POJO values during deserialization; a null entry would corrupt the resolver chain, so Jackson rejects it immediately.

Solutions

  1. Only call withValueInstantiators(instantiators) when instantiators != null.
  2. If you want a no-op resolver, implement ValueInstantiators returning null from findValueInstantiator instead of passing null for the provider itself.
  3. Verify the lookup/factory producing ValueInstantiators never returns null.

Example fix

// before
factoryConfig.withValueInstantiators(resolveInstantiators());

// after
ValueInstantiators vi = resolveInstantiators();
if (vi != null) {
    factoryConfig.withValueInstantiators(vi);
}
Defensive patterns

Strategy: validation

Validate before calling

ValueInstantiators vi = resolveInstantiators();
if (vi == null) {
    // skip
} else {
    factoryConfig.withValueInstantiators(vi);
}

Prevention

When it happens

Trigger: Registering a null ValueInstantiators via DeserializerFactoryConfig.withValueInstantiators(null), or a Module.setupModule passing null when adding value instantiators to the factory config.

Common situations: A module that conditionally supplies a ValueInstantiators and forgets the null branch; DI wiring where the bean is missing; copy-paste from another factory method that left a null.

Related errors


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

Appendix: source

Thrown at src/main/java/tools/jackson/databind/cfg/DeserializerFactoryConfig.java:145

        ValueDeserializerModifier[] all = ArrayBuilders.insertInListNoDup(_modifiers, modifier);
        return new DeserializerFactoryConfig(_additionalDeserializers, _additionalKeyDeserializers,
                all, _valueInstantiators);
    }

    /**
     * Fluent/factory method used to construct a configuration object that
     * has same configuration as this instance plus specified additional
     * value instantiator provider object.
     * Added instantiator provider has the highest priority (that is, it
     * gets called before any already registered resolver).
     *
     * @param instantiators Object that can provide {@link tools.jackson.databind.deser.ValueInstantiator}s for
     *    constructing POJO values during deserialization
     */
    public DeserializerFactoryConfig withValueInstantiators(ValueInstantiators instantiators)
    {
        if (instantiators == null) {
            throw new IllegalArgumentException("Cannot pass null resolver");
        }
        ValueInstantiators[] all = ArrayBuilders.insertInListNoDup(_valueInstantiators, instantiators);
        return new DeserializerFactoryConfig(_additionalDeserializers, _additionalKeyDeserializers,
                _modifiers, all);
    }

    public boolean hasDeserializers() { return _additionalDeserializers.length > 0; }

    public boolean hasKeyDeserializers() { return _additionalKeyDeserializers.length > 0; }

    public boolean hasDeserializerModifiers() { return _modifiers.length > 0; }

    public boolean hasValueInstantiators() { return _valueInstantiators.length > 0; }

    public Iterable<Deserializers> deserializers() {
        return new ArrayIterator<Deserializers>(_additionalDeserializers);
    }

View on GitHub (pinned to 87876ca5c0)