{"record":{"id":"a2f0bdf2769cd301","repo":"MuntashirAkon/AppManager","slug":"resetting-to-invalid-mark","errorCode":null,"errorMessage":"Resetting to invalid mark","messagePattern":"Resetting to invalid mark","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libcore/io/src/main/java/io/github/muntashirakon/io/SplitInputStream.java","lineNumber":117,"sourceCode":"        // Reset mark\n        mMarkPos = mPos;\n        mMarkBufCount = 0;\n        mMarkBuf = null;\n\n        int remain = mCount - mPos;\n        if (readlimit <= remain) {\n            // Don't need a separate buffer\n            mMarkBufSize = 0;\n        } else {\n            // Extra buffer required is remain + n * buf.length\n            mMarkBufSize = remain + ((readlimit - remain) / mBuf.length) * mBuf.length;\n        }\n    }\n\n    @Override\n    public synchronized void reset() throws IOException {\n        if (mMarkPos < 0)\n            throw new IOException(\"Resetting to invalid mark\");\n        // Switch to markPos or use markBuf\n        mPos = mMarkBuf == null ? mMarkPos : ~0;\n    }\n\n    @WorkerThread\n    @Override\n    public synchronized int available() throws IOException {\n        if (mCount < 0) return 0;\n        if (mPos >= mCount) {\n            // Try to read the next chunk into memory\n            read0(null, 0, 1);\n            if (mCount < 0) return 0;\n            // Revert the 1 byte read\n            --mPos;\n        }\n        // Return the size available in memory\n        if (mPos < 0) {\n            return (mMarkBufCount - ~mPos) + mCount;","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/io/src/main/java/io/github/muntashirakon/io/SplitInputStream.java#L99-L135","documentation":"SplitInputStream.reset() throws IOException(\"Resetting to invalid mark\") when no valid mark position exists (mMarkPos < 0). As with InputStream generally, reset() is only legal after mark() has been called and the read limit has not been exceeded. The stream cannot rewind without a recorded mark.","triggerScenarios":"Calling reset() on a SplitInputStream before ever calling mark(), or after reading more bytes than the marklimit supplied to mark(), which invalidates the mark.","commonSituations":"Parser code that assumes mark/reset support is always available; forgetting that mark() was never called on that stream instance; reading past the mark limit in a large buffer.","solutions":["Call mark(int readlimit) before reset() and ensure fewer than readlimit bytes are consumed","Use markSupported() to verify support and guard the reset call","Reopen or re-create the stream instead of resetting when no mark exists"],"exampleFix":"// before\nstream.reset();\n// after\nif (stream.markSupported() && marked) {\n    stream.reset();\n} else {\n    stream = reopenStream();\n}","handlingStrategy":"validation","validationCode":"if (stream.markSupported() && marked && consumedWithinLimit) stream.reset();","typeGuard":"boolean canReset(InputStream in, boolean marked) { return in.markSupported() && marked; }","tryCatchPattern":"try {\n    stream.reset();\n} catch (IOException e) {\n    // no valid mark: reopen the stream instead\n}","preventionTips":["Always call mark(readlimit) before reset()","Track reads and stay within the mark limit","Check markSupported() before relying on mark/reset"],"tags":["java","io","stream-mark"],"backgroundTag":"invalid-state-transition","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}