MuntashirAkon/AppManager · error · IllegalStateException
Lingering data, call flush() before releasing.
Error message
Lingering data, call flush() before releasing.
What it means
FastDataOutput.release() refuses to recycle the writer while unwritten bytes remain in its internal buffer. The buffer must be flushed to the underlying OutputStream before the object is released, otherwise buffered data would be silently lost. This is a defensive IllegalStateException protecting against data loss on reuse.
Solutions
- Call flush() on the FastDataOutput before calling release() or close().
- If you do not care about the remaining data, understand it would be lost — flush is still required; alternatively close the underlying stream path properly.
- Audit the code path for a previously thrown IOException during writes that left the buffer partially filled; handle it before release.
Example fix
// before out.writeInt(42); out.release(); // IllegalStateException: Lingering data // after out.writeInt(42); out.flush(); out.release();
Defensive patterns
Strategy: try-catch
Validate before calling
// Not directly observable; ensure flush ordering instead. if (out instanceof FastDataOutput) ((FastDataOutput) out).flush();
Try / catch
try {
out.flush();
} catch (IOException e) {
// log flush failure; buffer state now indeterminate
}
out.release(); Prevention
- Always call flush() immediately before release() or close() on FastDataOutput.
- Use try/finally so flush happens even when write code throws.
- Never release a writer whose writes may have failed without first attempting flush.
When it happens
Trigger: Calling release() (or close(), which delegates to release()) while mBufferPos > 0, i.e. after write calls without a preceding flush() or without writing enough data to trigger an automatic buffer flush.
Common situations: Forgetting to flush before closing; wrapping the writer in code that releases the object directly instead of calling flush() first; swallowing an IOException from an earlier flush and then attempting release; relying on close() semantics when the buffer still holds pending bytes.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- ADB command did not produce
- APK files backup is requested but no APK files have been…
- APPEND + TRUNCATE not allowed
- Array Size=" + array.length + ", offset=" + off + "…
- Backup failed for
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/ce0aba2b007923c6.
Report an issue: GitHub.
Appendix: source
Thrown at libcore/compat/src/main/java/io/github/muntashirakon/compat/io/FastDataOutput.java:111
* which specifies that large code-points must be encoded with 3-byte
* sequences.
*/
public static FastDataOutput obtainUsing4ByteSequences(@NonNull OutputStream out) {
FastDataOutput instance = sOutCache.getAndSet(null);
if (instance != null) {
instance.setOutput(out);
return instance;
}
return new FastDataOutput(out, DEFAULT_BUFFER_SIZE, true /* use4ByteSequence */);
}
/**
* Release a {@link FastDataOutput} to potentially be recycled. You must not
* interact with the object after releasing it.
*/
public void release() {
if (mBufferPos > 0) {
throw new IllegalStateException("Lingering data, call flush() before releasing.");
}
mOut = null;
mBufferPos = 0;
mStringRefs.clear();
if (mBufferCap == DEFAULT_BUFFER_SIZE && mUse4ByteSequence) {
// Try to return to the cache.
sOutCache.compareAndSet(null, this);
}
}
/**
* Re-initializes the object for the new output.
*/
private void setOutput(@NonNull OutputStream out) {
mOut = Objects.requireNonNull(out);
mBufferPos = 0;View on GitHub (pinned to 0152f468fc)