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
- Keep and reuse the exact object references returned/stored by the queue and only call changeKey on those.
- Track live membership in your own IdentityHashMap<element,Boolean> mirroring insertion/removal.
- 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
- Reuse stored element references; never reconstruct equal copies for key changes.
- Track live membership in an IdentityHashMap mirroring insertion/removal.
- In graph algorithms, mark nodes as settled and skip changeKey after extraction.
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.