TheAlgorithms/Java · error · IllegalArgumentException

Element not in queue

Error message

Element not in queue

What it means

Thrown by IndexedPriorityQueue.changeKey(E, Consumer) when index.get(e) returns null. The index is an IdentityHashMap, so membership is tested by reference identity, not equals. A null index means the element was never inserted, was already removed/polled, or a different instance (even an equal one) was passed.

Source

Thrown at src/main/java/com/thealgorithms/datastructures/heaps/IndexedPriorityQueue.java:174

    }

    // ------------------------------------------------------------------------------------
    // Key update API
    // ------------------------------------------------------------------------------------

    /**
     * Changes comparator-relevant fields of {@code e} via the provided {@code mutator},
     * then restores the heap in O(log n) by bubbling in the correct direction.
     *
     * <p><b>IMPORTANT:</b> The mutator must not change {@code equals/hashCode} of {@code e}
     * if you migrate this implementation to value-based indexing (HashMap).
     *
     * @throws IllegalArgumentException if {@code e} is not in the queue
     */
    public void changeKey(E e, Consumer<E> mutator) {
        Integer i = index.get(e);
        if (i == null) {
            throw new IllegalArgumentException("Element not in queue");
        }
        // Mutate fields used by comparator (do NOT mutate equality/hash if using value-based map)
        mutator.accept(e);
        // Try bubbling up; if no movement occurred, bubble down.
        if (!siftUp(i)) {
            siftDown(i);
        }
    }

    /**
     * Faster variant if the new key is strictly smaller (higher priority).
     * Performs a single sift-up (O(log n)).
     */
    public void decreaseKey(E e, Consumer<E> mutator) {
        Integer i = index.get(e);
        if (i == null) {
            throw new IllegalArgumentException("Element not in queue");
        }

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Keep and reuse the exact object references returned/stored by the queue and only call changeKey on those.
  2. Track live membership in your own IdentityHashMap<element,Boolean> mirroring insertion/removal.
  3. Do not reconstruct equal-but-different element instances and pass them to changeKey; identity will not match.

Example fix

// before
ipq.changeKey(node, n -> n.dist = newDist);

// after
if (ipq.contains(node)) {  // or your own live-set check
    ipq.changeKey(node, n -> n.dist = newDist);
}
Defensive patterns

Strategy: validation

Validate before calling

// IdentityHashMap index: use reference-equality live set
IdentityHashMap<E, Boolean> live = new IdentityHashMap<>();
// on insert: live.put(e, true);  on remove/poll: live.remove(e);
if (live.containsKey(e)) {
    ipq.changeKey(e, mutator);
}

Try / catch

try {
    ipq.changeKey(e, mutator);
} catch (IllegalArgumentException ex) {
    // element not in queue; re-insert or ignore
}

Prevention

When it happens

Trigger: Calling changeKey on an element never inserted; on an element already returned by a poll/remove; passing a freshly reconstructed object that equals a stored one but is not the same instance.

Common situations: Dijkstra relaxation after a node was settled and extracted; reusing element references after they were polled; value-based lookups that assume equals semantics.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/7ddbf24fb630f60b. Report an issue: GitHub.