🔴 The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOGException in thread "main" java.lang.IllegalArgumentException: No enum constant com.devinhyderabad.pay.Status.COMPLTED at java.base/java.lang.Enum.valueOf(Enum.java:273) at com.devinhyderabad.pay.Status.valueOf(Status.java:3) at com.devinhyderabad.pay.StatusMain.main(StatusMain.java:5) // Second famous tenant — TimSort legality check (DOC-DERIVED canonical): Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.base/java.util.TimSort.mergeHi(TimSort.java:<v>) at java.base/java.util.TimSort.mergeAt(TimSort.java:<v>) at java.base/java.util.Arrays.sort(Arrays.java:<v>) at com.devinhyderabad.reports.Leaderboard.rank(Leaderboard.java:20)

⚡ Quick Fix Works 80% of the time

Never feed unvetted strings into valueOf — wrap lookups in a safe helper returning Optional or a default.

public static <E extends Enum<E>> Optional<E> lookup( Class<E> type, String raw) { if (raw == null) return Optional.empty(); try { return Optional.of(Enum.valueOf(type, raw.trim())); } catch (IllegalArgumentException e) { return Optional.empty(); } }

🧠 Why this Happens

Tap to expand the deep technical explanation

The compiler generates Status.valueOf as a thin delegate to Enum.valueOf, which hashes the requested name against the $VALUES directory built reflectively during enum class initialization. A miss produces the concatenated diagnostic "No enum constant <class>.<name>". The TimSort side is defensive engineering: since JDK 7, merge routines verify run invariants as they combine sorted runs, and contradictory comparisons prove the Comparator broke transitivity/sign-consistency — throwing beats silently returning wrongly-sorted data, which is exactly what pre-7 merge sort did.

The HITEC City Parking Spot Analogy:

Enum lookup is a hotel front desk matching guests by EXACT spelling: COMPLTED is not on the list no matter how close it looks to COMPLETED. TimSort is a referee who stops the whole tournament the moment two judges submit contradictory rankings.

🔁 How to Reproduce Confirm this is your error

Define enum Status { ACTIVE, PAUSED } and call Status.valueOf("COMPLTED") — instant throw captured verbatim on OpenJDK 17 (Enum.java line reads 293 on JDK 25). The TimSort block needs a contract-violating Comparator over a large list; deterministic repro is fiddly, so that block stays documentation-canonical.

🛠️ Solutions (5 Ways to Fix)

Solution 1✓ Most common cause

Safe enum lookup: Optional/default instead of valueOf crash

👉 Use this whenever enum values cross a boundary — DB columns, wire payloads, CSV cells, query params.

Stored values drift from enum names constantly: typos like COMPLTED, casing changes, renamed constants after deploy. Centralize tolerant lookup once; normalize case if your domain allows, and choose an explicit fallback instead of letting a typo kill a request.

Status s = lookup(Status.class, dbValue) .orElseThrow(() -> new IllegalStateException( "unknown status stored: [" + dbValue + "]")); // Or tolerate-and-default where business rules allow: Status lenient = lookup(Status.class, dbValue).orElse(Status.ACTIVE);
Solution 2

Fix comparator overflow — the #1 TimSort killer

👉 Use this when the trace shows Comparison method violates its general contract!.

(a, b) -> a.score - b.score breaks when subtraction overflows int (2_000_000_000 minus -2_000_000_000 wraps negative), flipping comparison signs mid-sort. TimSort detects the inconsistency across merge runs and throws rather than emit corrupt orderings. Always Comparator.comparingX — never hand-subtracted keys.

// BROKEN: overflow flips signs on extreme scores items.sort((a, b) -> a.score() - b.score()); // FIXED: items.sort(Comparator.comparingInt(Item::score)); // Doubles: Double.compare(a.weight(), b.weight())
Solution 3

Throw IAE yourself — early and descriptively

👉 Use this when writing API entry points that receive caller-supplied values.

IllegalArgumentException is the CORRECT tool for caller mistakes: validate at method entry with a message naming the parameter and the offending value. A clear IAE at the boundary beats a deep mysterious failure three layers later.

public void schedule(Job job, int retries) { if (retries < 0 || retries > 10) { throw new IllegalArgumentException( "retries must be 0..10, got " + retries); } ... }
Solution 4

Map the subclass family your catches inherit

👉 Use this to reason about what catch (IllegalArgumentException) really captures.

NumberFormatException and IllegalThreadStateException both EXTEND IAE — catching IAE nets parse failures and thread-state misuse too. Useful for broad guards at edges; harmful mid-stack when you meant to isolate only parsing. The hierarchy runs: RuntimeException -> IllegalArgumentException -> {NumberFormatException, IllegalThreadStateException}.

catch (IllegalArgumentException e) { // also lands here: // NumberFormatException ("For input string: ...") // IllegalThreadStateException (start() twice, etc.) }
Solution 5

Standardize range checks with Objects.check* helpers

👉 Use this for index/range contracts instead of hand-written if-throw chains.

Objects.checkIndex/checkFromToIndex (Java 9+) produce descriptive IndexOutOfBoundsException wording consistently and document intent. Same fail-fast philosophy as IAE with standard library backing.

int safeFrom = Objects.checkIndex(from, items.size()); int safeTo = Objects.checkFromToIndex(from, to, items.size()); return items.subList(safeFrom, safeTo);

📋 Version Notes

Java 8

Both famous messages already present ("No enum constant", TimSort contract); Enum.valueOf frame lacks module prefix.

Java 9

java.base/-prefixed frames appear; Objects.checkIndex family added to java.util.Objects.

Java 17

Captured wording byte-identical vs JDK 25; internal Enum.valueOf line numbers drift between builds (273@17, 293@25).

Java 21

Unchanged; pattern-matching switch adds new ways to AVOID valueOf crashes, not new messages.

🛡️ How to Prevent This Next Time

Funnel all external values through centralized tolerant lookups, ban manual subtraction comparators via review/lint, validate parameters at entry with parameter-naming messages, and unit-test enums against every legacy stored value.