{"record":{"id":"047ac355ac9544d7","repo":"oracle/graal","slug":"partial-character-at-end","errorCode":null,"errorMessage":"Partial character at end","messagePattern":"Partial character at end","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryInput.java","lineNumber":289,"sourceCode":"            switch (c1 >> 4) {\n                case 0:\n                case 1:\n                case 2:\n                case 3:\n                case 4:\n                case 5:\n                case 6:\n                case 7:\n                    /* 0xxxxxxx */\n                    byteCount++;\n                    tempEncodingCharBuffer[charCount++] = (char) c1;\n                    break;\n                case 12:\n                case 13:\n                    /* 110x xxxx 10xx xxxx */\n                    byteCount += 2;\n                    if (byteCount > len) {\n                        throw new IllegalArgumentException(\"Partial character at end\");\n                    }\n                    c2 = tempEncodingByteBuffer[byteCount - 1];\n                    if ((c2 & 0xC0) != 0x80) {\n                        throw new IllegalArgumentException(\"malformed input around byte \" + byteCount);\n                    }\n                    tempEncodingCharBuffer[charCount++] = (char) (((c1 & 0x1F) << 6) | (c2 & 0x3F));\n                    break;\n                case 14:\n                    /* 1110 xxxx 10xx xxxx 10xx xxxx */\n                    byteCount += 3;\n                    if (byteCount > len) {\n                        throw new IllegalArgumentException(\"malformed input: partial character at end\");\n                    }\n                    c2 = tempEncodingByteBuffer[byteCount - 2];\n                    c3 = tempEncodingByteBuffer[byteCount - 1];\n                    if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) {\n                        throw new IllegalArgumentException(\"malformed input around byte \" + (byteCount - 1));\n                    }","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryInput.java#L271-L307","documentation":"BinaryInput.readUTF decodes the internal UTF-8-like stream used to marshal strings between Truffle/libgraal and its peer. When a 2-byte sequence (lead byte 110xxxxx) starts near the end of the buffer and its continuation byte is missing, it throws IllegalArgumentException('Partial character at end'). This mirrors java.io.DataInputStream's modified-UTF8 error semantics.","triggerScenarios":"Reading a STRING-tagged value from a BinaryInput where the byte buffer is truncated mid multi-byte character: a mismatch between the declared payload length and the actual encoded string bytes.","commonSituations":"Corrupted or partially written marshalled data; a producer/consumer version mismatch changing the wire format; reading from a native memory buffer that was freed or resized mid-transfer.","solutions":["Verify producer and consumer use the same libgraal/Truffle marshalling format (same GraalVM version on both sides).","Check that the byte count/header written by BinaryOutput.writeUTF matches what BinaryInput.readUTF consumes.","Reproduce with logging around the read to confirm the buffer length is not truncated by an earlier short read.","If the stream is corrupted, discard and regenerate the marshalled payload rather than retrying reads."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify buffer has room for the full sequence before readUTF\n// (framing sanity: header length must not exceed remaining bytes)","typeGuard":null,"tryCatchPattern":"try {\n    String s = in.readUTF();\n} catch (IllegalArgumentException e) {\n    if (\"Partial character at end\".equals(e.getMessage())) {\n        // truncated payload: request re-transfer of the whole record\n    }\n}","preventionTips":["Always write strings with BinaryOutput.writeUTF so lengths are exact","Verify transferred byte counts match headers","Keep producer and consumer on the same GraalVM version"],"tags":["libgraal","truffle","encoding","utf-8","marshalling"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}