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

  1. Call flush() on the FastDataOutput before calling release() or close().
  2. 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.
  3. 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

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


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)