MuntashirAkon/AppManager · error · IllegalStateException
Unexpected CharBuffer position: actual=" +…
Error message
Unexpected CharBuffer position: actual=" + mCharBuffer.position() + " expected=" + mCharBufferMark
What it means
reset() restores the stream to a previously set mark. The library throws IllegalStateException when, after refilling buffers, the CharBuffer position does not match the recorded mark (mCharBufferMark). This indicates an internal decoder buffering invariant was broken, typically because the internal buffers were consumed beyond the marked position.
Solutions
- Call mark(readLimit) with a readLimit large enough to cover all bytes read before reset().
- Always pair mark()/reset() and never reset() after the mark has been invalidated by excessive reads.
- Re-create the CharSequenceInputStream from the source CharSequence instead of resetting an exhausted mark.
Example fix
// before stream.mark(8); stream.read(buf, 0, 1024); stream.reset(); // after stream.mark(4096); stream.read(buf, 0, 1024); stream.reset();
Defensive patterns
Strategy: validation
Validate before calling
boolean canReset = !resetCalledOnce && bytesReadSinceMark < markedReadLimit;
if (!canReset) throw new IllegalStateException("Mark no longer valid"); Try / catch
try {
stream.reset();
} catch (IllegalStateException e) {
stream = new CharSequenceInputStream(source, charset); // recreate instead
} Prevention
- Set mark(readLimit) generously larger than expected reads
- Never call reset() without a prior mark()
- Track bytes read between mark and reset
When it happens
Trigger: Calling reset() after reading past the marked region so far that the internal CharBuffer was refilled/rewound and its position can no longer be restored to mCharBufferMark (mark invalidated by too much reading since mark()).
Common situations: Calling reset() without a preceding mark(); reading more bytes than readLimit allows between mark() and reset(); calling reset() twice.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Cannot write more data, the end of the compressed data…
- 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 + "…
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/873b6f71361bfec0.
Report an issue: GitHub.
Appendix: source
Thrown at libcore/io/src/main/java/io/github/muntashirakon/io/CharSequenceInputStream.java:224
// the mark. The code would have to catch InvalidMarkException - does not seem possible to check if mark is
// valid otherwise. + Try saving the state of the cBuf before each fillBuffer; it might be possible to
// restart from there.
//
if (mCharBufferMark != NO_MARK) {
// if cBuf is at 0, we have not started reading anything, so skip re-encoding
if (mCharBuffer.position() != 0) {
mCharsetEncoder.reset();
mCharBuffer.rewind();
mByteBuffer.rewind();
mByteBuffer.limit(0); // rewind does not clear the buffer
while (mCharBuffer.position() < mCharBufferMark) {
mByteBuffer.rewind(); // empty the buffer (we only refill when empty during normal processing)
mByteBuffer.limit(0);
fillBuffer();
}
}
if (mCharBuffer.position() != mCharBufferMark) {
throw new IllegalStateException("Unexpected CharBuffer position: actual=" + mCharBuffer.position() + " " +
"expected=" + mCharBufferMark);
}
mByteBuffer.position(mByteBufferMark);
mCharBufferMark = NO_MARK;
mByteBufferMark = NO_MARK;
}
}
@Override
public long skip(long n) throws IOException {
//
// This could be made more efficient by using position to skip within the current buffer.
//
long skipped = 0;
while (n > 0 && available() > 0) {
read();
n--;
skipped++;View on GitHub (pinned to 0152f468fc)