Tencent/tinker · error · IllegalArgumentException
Bad size: ${value}
Error message
Bad size: ${value} What it means
setSize sets the uncompressed size of an entry, which the zip format stores as a non-negative quantity. A negative value throws IllegalArgumentException('Bad size'). Note this library's guard is only value < 0 — unlike the Harmony/Android original it does not enforce the 32-bit zip1 limit here, but a negative size always indicates uninitialized or corrupted state in the caller (e.g. -1 'unknown' sentinel).
Source
Thrown at third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/TinkerZipEntry.java:351
/**
* Gets the uncompressed size of this {@code ZipEntry}.
*
* @return the uncompressed size, or {@code -1} if the size has not been
* set.
*/
public long getSize() {
return size;
}
/**
* Sets the uncompressed size of this {@code ZipEntry}.
*
* @param value the uncompressed size for this entry.
* @throws IllegalArgumentException if {@code value < 0}.
*/
public void setSize(long value) {
if (value < 0) {
throw new IllegalArgumentException("Bad size: " + value);
}
size = value;
}
/**
* Gets the last modification time of this {@code ZipEntry}.
*
* @return the last modification time as the number of milliseconds since
* Jan. 1, 1970.
*/
public long getTime() {
if (time != -1) {
GregorianCalendar cal = new GregorianCalendar();
cal.set(Calendar.MILLISECOND, 0);
cal.set(1980 + ((modDate >> 9) & 0x7f), ((modDate >> 5) & 0xf) - 1,
modDate & 0x1f, (time >> 11) & 0x1f, (time >> 5) & 0x3f,
(time & 0x1f) << 1);
return cal.getTime().getTime();View on GitHub (pinned to 1b7ea02c23)
Solutions
- Only call setSize when you have a real non-negative size; skip the call entirely if the source reports -1 (unknown).
- Compute sizes from the actual data (e.g. after reading the stream) rather than propagating sentinels.
- Check for -1 explicitly and throw your own descriptive error upstream, so the failure is not buried in the zip writer.
Example fix
// before
long srcSize = sourceEntry.getSize(); // -1 when unset
newEntry.setSize(srcSize);
// after
long srcSize = sourceEntry.getSize();
if (srcSize >= 0) {
newEntry.setSize(srcSize);
} Defensive patterns
Strategy: validation
Validate before calling
long sz = sourceEntry.getSize();
if (sz >= 0) {
newEntry.setSize(sz);
}
// skip the call when sz == -1 (unknown) Prevention
- Treat -1 from getSize() as 'unknown' and omit the setSize call.
- Compute sizes from actual data when the source does not provide them.
- Never use negative sentinels as placeholder sizes in your own entry model.
When it happens
Trigger: Calling setSize(value) with value < 0, most commonly forwarding -1 from an API that uses -1 to mean 'size unknown' (java.util.zip.ZipEntry.getSize returns -1 when unset), or a subtraction that underflowed.
Common situations: Reading sizes from a parsed central directory where the field failed to parse; copying from a source entry whose size was never set; using -1 as a placeholder before the real size is known.
Related errors
- Size mismatch
- ${argument} too long: ${bytes.length}
- Bad CRC32: ${value}
- Extra data too long: ${data.length}
- Bad method: ${value}
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/c1587731ccf5cf7d.
Report an issue: GitHub.