{"record":{"id":"826300b3dd8162b8","repo":"quarkusio/quarkus","slug":"invalid-signature-char-c-in-signature-at-po","errorCode":null,"errorMessage":"Invalid signature char: ${c} in ${signature} at position ${i}","messagePattern":"Invalid signature char: (.+?) in (.+?) at position (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/util/types/TypeSignatureParser.java","lineNumber":66,"sourceCode":"                    break LOOP;\n                case 'V':\n                    ret = void.class;\n                    break LOOP;\n                // ClassTypeSignature\n                case 'L':\n                    ret = parseReference();\n                    break LOOP;\n                // TypeVariableSignature\n                case 'T':\n                    // Stef has come to the conclusion that because TypeVariable depends on the GenericDeclaration that defined them, which is lacking\n                    // in signatures unless we have access to the current context, we should not support them\n                    throw new IllegalArgumentException(\n                            \"Invalid type variable in signature: \" + new String(chars) + \" at position \" + i);\n                case '[':\n                    arrayCount++;\n                    break;\n                default:\n                    throw new IllegalArgumentException(\n                            \"Invalid signature char: \" + c + \" in \" + new String(chars) + \" at position \" + i);\n            }\n        } while (true);\n        if (arrayCount > 0) {\n            if (ret instanceof Class) {\n                Class<?> retClass = (Class<?>) ret;\n                if (retClass.isPrimitive()) {\n                    // load [I or [[I\n                    return loadClass(new String(chars, start, i - start));\n                }\n                // get the [L part and the name out of the class\n                return loadClass(new String(chars, start, arrayCount + 1) + retClass.getName() + \";\");\n            }\n            if (ret instanceof ParameterizedType) {\n                // this is a moronic API\n                for (int a = 0; a < arrayCount; a++) {\n                    ret = new GenericArrayTypeImpl(ret);\n                }","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/util/types/TypeSignatureParser.java#L48-L84","documentation":"TypeSignatureParser.parseType iterates over signature characters and only recognizes valid type-signature tokens (object types 'L...;', arrays '[', primitives like 'I', 'Z', etc.). Any other character reaches the default branch and throws this IllegalArgumentException identifying the bad char, the full signature, and the position.","triggerScenarios":"Calling TypeSignatureParser.parse with a malformed or truncated signature string, e.g. \"Ljava/util/List\" missing the terminating ';', \"X\" as a type, or a corrupted string built manually.","commonSituations":"Hand-written or programmatically truncated descriptor strings; signatures copied from bytecode dumps with offsets off by one; storing signatures in config/DB and losing characters.","solutions":["Verify the signature is a complete, valid JVM type signature (object types must end with ';')","Print the full signature and check the reported position for the offending character","Regenerate the signature instead of hand-crafting it (e.g. from Class.getName()/descriptor APIs)","Guard the parse call with try-catch and log the signature for diagnosis"],"exampleFix":"// before\nTypeSignatureParser.parse(\"Ljava/util/List\");\n// after\nTypeSignatureParser.parse(\"Ljava/util/List<Ljava/lang/String;>;\");","handlingStrategy":"try-catch","validationCode":"static boolean looksLikeTypeSignature(String s) {\n    return s != null && !s.isEmpty()\n        && (s.startsWith(\"L\") && s.endsWith(\";\") || s.startsWith(\"[\") || \"BCDFIJSZV\".indexOf(s.charAt(0)) >= 0);\n}","typeGuard":null,"tryCatchPattern":"try {\n    Type t = TypeSignatureParser.parse(signature);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Invalid signature char\")) {\n    log.error(\"Bad signature: \" + e.getMessage());\n    return null; // or re-generate the signature\n    } else throw e;\n}","preventionTips":["Generate signatures programmatically instead of hand-writing them","Verify object types terminate with ';' and primitives use valid descriptors","Keep signatures intact in storage/transport — watch for truncation","Log the full signature (the error includes it) to spot the offending char quickly"],"tags":["generics","reflection","signature-parsing"],"backgroundTag":"invalid-type-signature","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}