{"record":{"id":"31f2a2d2ca0c79dd","repo":"quarkusio/quarkus","slug":"no-tccl-available","errorCode":null,"errorMessage":"No TCCL available","messagePattern":"No TCCL available","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/AbstractGenerator.java","lineNumber":33,"sourceCode":"    static final String UNDERSCORE = \"_\";\n    static final String SYNTHETIC_SUFFIX = \"Synthetic\";\n\n    protected final boolean generateSources;\n    protected final ReflectionRegistration reflectionRegistration;\n\n    public AbstractGenerator(boolean generateSources, ReflectionRegistration reflectionRegistration) {\n        this.generateSources = generateSources;\n        this.reflectionRegistration = reflectionRegistration;\n    }\n\n    public AbstractGenerator(boolean generateSources) {\n        this(generateSources, null);\n    }\n\n    static Gizmo gizmo(ClassOutput classOutput) {\n        ClassLoader tccl = Thread.currentThread().getContextClassLoader();\n        if (tccl == null) {\n            throw new IllegalStateException(\"No TCCL available\");\n        }\n        return Gizmo.create(classOutput)\n                .withDebugInfo(false)\n                .withParameters(false)\n                .withLambdasAsAnonymousClasses(true);\n    }\n\n    /**\n     * Generates a class name from a target package, base name and suffix. When the class\n     * is located in a default package, the target package name is an empty string.\n     *\n     * @param targetPackage name of the target package\n     * @param baseName simple class name\n     * @param suffix suffix to append to the generated name\n     * @return generated name\n     */\n    static String generatedNameFromTarget(String targetPackage, String baseName, String suffix) {\n        if (targetPackage == null || targetPackage.isEmpty()) {","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/AbstractGenerator.java#L15-L51","documentation":"Arc's AbstractGenerator.gizmo(ClassOutput) reads the current thread context classloader to configure bytecode generation. If Thread.currentThread().getContextClassLoader() returns null, it throws IllegalStateException because the generator needs a classloader to operate.","triggerScenarios":"Calling Gizmo.gizmo(classOutput) from a thread whose context classloader has not been set (null TCCL).","commonSituations":"Threads spawned manually in build steps without inheriting/setting a TCCL; running generation in unusual environments (custom executors, native-image tooling) where TCCL is unset.","solutions":["Set the TCCL before invoking: Thread.currentThread().setContextClassLoader(YourClass.class.getClassLoader())","Run generation on a thread that inherits the application/build classloader","Wrap the call in a block that saves and restores an explicit classloader"],"exampleFix":"// before\nGizmo gizmo = AbstractGenerator.gizmo(classOutput); // TCCL null -> throws\n// after\nClassLoader old = Thread.currentThread().getContextClassLoader();\nThread.currentThread().setContextClassLoader(AbstractGenerator.class.getClassLoader());\ntry {\n    Gizmo gizmo = AbstractGenerator.gizmo(classOutput);\n} finally {\n    Thread.currentThread().setContextClassLoader(old);\n}","handlingStrategy":"validation","validationCode":"if (Thread.currentThread().getContextClassLoader() == null) Thread.currentThread().setContextClassLoader(AbstractGenerator.class.getClassLoader());","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set TCCL on custom threads before generation"],"tags":["arc","cdi","classloader","build-time"],"backgroundTag":"missing-thread-context-classloader","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"}