FasterXML/jackson-databind · error · IllegalArgumentException

Trying to resolve a forward reference with id [{}] that wasn

Error message

Trying to resolve a forward reference with id [{}] that wasn't previously seen as unresolved.

What it means

Thrown by CollectionDeserializer.CollectionReferringAccumulator.resolveForwardReference when an attempt is made to resolve a forward reference using an id that does not match any pending CollectionReferring entry in the accumulator. The accumulator tracks unresolved forward references during collection deserialization (for collections containing @JsonIdentityInfo objects) and iterates its internal list to find a match; if none is found, it throws IllegalArgumentException.

Source

Thrown at src/main/java/tools/jackson/databind/deser/jdk/CollectionDeserializer.java:659

        public void resolveForwardReference(DeserializationContext ctxt, Object id, Object value) throws JacksonException
        {
            Iterator<CollectionReferring> iterator = _accumulator.iterator();
            // Resolve ordering after resolution of an id. This mean either:
            // 1- adding to the result collection in case of the first unresolved id.
            // 2- merge the content of the resolved id with its previous unresolved id.
            Collection<Object> previous = _result;
            while (iterator.hasNext()) {
                CollectionReferring ref = iterator.next();
                if (ref.hasId(id)) {
                    iterator.remove();
                    previous.add(value);
                    previous.addAll(ref.next);
                    return;
                }
                previous = ref.next;
            }

            throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id
                    + "] that wasn't previously seen as unresolved.");
        }

        /**
         * Replace a resolved item in the result collection. Called when the bound
         * item is rebound (e.g., builder → built object) via
         * {@link Referring#handleItemRebind}.
         *
         * @param oldItem Item to replace (Builder)
         * @param newItem Item to replace {@code oldItem} with (Built value)
         *
         * @since 3.2
         */
        public void replaceResolvedItem(Object oldItem, Object newItem) {
            if (_result instanceof List<?>) {
                @SuppressWarnings("unchecked")
                List<Object> list = (List<Object>) _result;
                for (int i = 0, len = list.size(); i < len; i++) {

View on GitHub (pinned to a50c7d2a1d)

Solutions

  1. Ensure the JSON array contains definitions for all referenced object ids.
  2. Verify @JsonIdentityInfo scope and generator are consistent across all types in the collection.
  3. If using manual resolution, collect ids only from the accumulator's pending references.
  4. Check for duplicate ids in the JSON that might confuse the accumulator's ordering logic.

Example fix

// before: array references id 3 which is never defined
[{"ref":3},{"ref":3}]
// after: include definition of id 3
[{"@id":3,"name":"foo"},{"ref":3}]
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate JSON contains all object ids referenced in collection values
JsonNode tree = mapper.readTree(json);
Set<Object> defined = extractAllIds(tree);
Set<Object> referenced = extractAllRefs(tree);
if (!defined.containsAll(referenced)) {
    throw new IllegalStateException("Unresolved collection ids: " +
        Sets.difference(referenced, defined));
}

Try / catch

try {
    mapper.readValue(json, new TypeReference<List<MyType>>() {});
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("wasn't previously seen as unresolved")) {
        // JSON is missing an object id definition — fix the data source
    }
}

Prevention

When it happens

Trigger: Deserializing a Collection<@JsonIdentityInfo-annotated-type> where the JSON contains forward object-id references. The framework attempts to resolve an id that was never registered as pending during collection element deserialization. Manual resolution with an unknown id.

Common situations: JSON arrays with object identity references where some ids are never defined in the document. Inconsistent @JsonIdentityInfo configuration between the collection element type and the referencing type. Deserializing a partial or truncated array. Stream-based deserialization where not all elements have been read before resolution is attempted.

Related errors


AI-assisted analysis of FasterXML/jackson-databind@a50c7d2a1d (2026-08-06). Data as JSON: /api/errors/42475c4fbe8992cd. Report an issue: GitHub.