{"record":{"id":"38da897db796f261","repo":"quarkusio/quarkus","slug":"unknown-start-character-for-json-value-s","errorCode":null,"errorMessage":"Unknown start character for json value: %s","messagePattern":"Unknown start character for json value: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/builder/src/main/java/io/quarkus/builder/JsonReader.java","lineNumber":88,"sourceCode":"\n        switch (ch) {\n            case '{':\n                return readObject();\n            case '[':\n                return readArray();\n            case '\"':\n                return readString();\n            case 't':\n                return readConstant(\"true\", JsonBoolean.TRUE);\n            case 'f':\n                return readConstant(\"false\", JsonBoolean.FALSE);\n            case 'n':\n                return readConstant(\"null\", JsonNull.INSTANCE);\n            default:\n                if (Character.isDigit(ch) || '-' == ch) {\n                    return readNumber(position);\n                }\n                throw new IllegalArgumentException(\"Unknown start character for json value: \" + ch);\n        }\n    }\n\n    /**\n     * object\n     * |---- '{' ws '}'\n     * |---- '{' members '}'\n     * </p>\n     * members\n     * |----- member\n     * |----- member ',' members\n     */\n    private JsonValue readObject() {\n        position++;\n\n        Map<JsonString, JsonValue> members = new HashMap<>();\n\n        while (position < length) {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/builder/src/main/java/io/quarkus/builder/JsonReader.java#L70-L106","documentation":"GreetingResource.hello (POST, application/octet-stream) throws \"bad input\" when the received byte array's first four bytes are not 0,1,2,3. The endpoint is a strict binary protocol check: any payload whose magic prefix differs is rejected.","triggerScenarios":"POSTing an octet-stream body whose bytes[0..3] are not exactly 0x00 0x01 0x02 0x03 — including empty/short bodies that make bytes[i] throw ArrayIndexOutOfBounds under this error path.","commonSituations":"Client sending JSON/text instead of the expected binary prefix; test fixture bytes misordered; compression/encoding altering the first bytes; sending fewer than 4 bytes.","solutions":["Send a payload whose first four bytes are 0,1,2,3 (e.g. new byte[]{0,1,2,3,...}).","Ensure Content-Type is application/octet-stream so the byte[] body deserializes as raw bytes.","Add a length guard (bytes.length < 4) to avoid a separate ArrayIndexOutOfBoundsException.","Verify no intermediary (gzip, base64) transforms the binary body."],"exampleFix":"// before\nbyte[] body = \"hello\".getBytes(); // fails magic check\n// after\nbyte[] body = new byte[]{0, 1, 2, 3, 4, 5};\n// Content-Type: application/octet-stream","handlingStrategy":"try-catch","validationCode":"Response head = given().header(\"tenantId\", tenant).get(\"/fruits/\" + id);\nif (head.getStatusCode() == 404) return; // already gone","typeGuard":null,"tryCatchPattern":"Response r = given().header(\"tenantId\", tenant).delete(\"/fruits/\" + id);\nswitch (r.getStatusCode()) {\n    case 204: break;                      // deleted\n    case 404: break;                      // idempotent no-op\n    default: throw new AssertionError(\"Unexpected delete status \" + r.getStatusCode());\n}","preventionTips":["Model delete as idempotent to tolerate repeat calls","Verify tenant header matches data owner before DELETE","Use runtime-generated ids from the same test run","Clean up in reverse order of creation to avoid stale-id deletes"],"tags":["rest","jaxrs","binary","validation"],"backgroundTag":"invalid-request-payload","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}