TheAlgorithms/Java · error · IllegalArgumentException
Bad compressed k: {}
Error message
Bad compressed k: {} What it means
LZW.decompress walks the code list rebuilding the dictionary. For each code k it must either exist in the current dictionary or equal dictSize (the special next-code case). If k is neither in the dictionary nor the next available code, the stream is invalid — the code references a string that cannot be reconstructed, so the method rejects the corrupt input.
Source
Thrown at src/main/java/com/thealgorithms/compression/LZW.java:124
Map<Integer, String> dictionary = new HashMap<>();
for (int i = 0; i < dictSize; i++) {
dictionary.put(i, "" + (char) i);
}
// Decompress the first code
String w = "" + (char) (int) compressed.removeFirst();
StringBuilder result = new StringBuilder(w);
for (int k : compressed) {
String entry;
if (dictionary.containsKey(k)) {
// The code is in the dictionary
entry = dictionary.get(k);
} else if (k == dictSize) {
// Special case for sequences like "ababab"
entry = w + w.charAt(0);
} else {
throw new IllegalArgumentException("Bad compressed k: " + k);
}
result.append(entry);
// Add new sequence to the dictionary
dictionary.put(dictSize++, w + entry.charAt(0));
w = entry;
}
return result.toString();
}
}
View on GitHub (pinned to fdfb9a395b)
Solutions
- Pass the exact List<Integer> returned by LZW.compress without modification.
- Verify the list is non-null, ordered, and contains no gaps relative to the expected dictionary growth.
- Ensure compress and decompress use the same LZW implementation and initial dictionary (ASCII 0-255 here).
Example fix
// before List<Integer> codes = readCodesFromFile(); // may be corrupted/partial String out = LZW.decompress(codes); // after List<Integer> codes = LZW.compress(original); // produce + transport intact String out = LZW.decompress(codes);
Defensive patterns
Strategy: try-catch
Validate before calling
// Cannot fully validate a compressed stream without decoding; best pre-check is structural integrity.
if (compressed == null || compressed.isEmpty()) return "";
// Ensure codes are non-negative and ordered consistently with dictionary growth.
for (int k : compressed) {
if (k < 0) throw new IllegalArgumentException("Negative code in compressed stream: " + k);
} Try / catch
try {
String out = LZW.decompress(compressed);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Bad compressed k:")) {
// handle corrupt stream: log, request retransmission, or fall back
throw new IllegalStateException("LZW stream is corrupt or truncated", e);
}
throw e;
} Prevention
- Pass the exact List<Integer> from compress unchanged.
- Use the same LZW implementation for compress and decompress.
- Round-trip test compress->decompress to confirm the stream is self-consistent.
When it happens
Trigger: Calling decompress on a hand-edited or truncated list; decompress([99999]) where 99999 is far beyond any dictionary entry; codes reordered or a negative value inserted; mixing codes from a different compression run.
Common situations: The compressed code list was corrupted in storage/transit; a partial list was passed (missing leading codes so the dictionary never grew far enough); codes were produced by a different LZW variant/implementation.
Related errors
- Input string cannot be null or empty.
- Original index must be between 0 and {}, got: {}
- Character '%c' (U+%04X) not found in Huffman dictionary.
- Invalid binary sequence for single-character tree.
- Encoded text contains invalid characters: {}
AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13).
Data as JSON: /api/errors/463ce38147b45fd4.
Report an issue: GitHub.