{"record":{"id":"7a1f0059d9c1abab","repo":"quarkusio/quarkus","slug":"classinfo-not-found-for-classname","errorCode":null,"errorMessage":"ClassInfo not found for ${className}","messagePattern":"ClassInfo not found for (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/scanning/ClassInjectorTransformer.java","lineNumber":99,"sourceCode":"            boolean requireCreateBeanParams, IndexView indexView) {\n        this.fieldExtractors = fieldExtractors;\n        this.superTypeIsInjectable = superTypeIsInjectable;\n        this.requireCreateBeanParams = requireCreateBeanParams;\n        this.indexView = indexView;\n    }\n\n    @Override\n    public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) {\n        ClassTransformer transformer = new ClassTransformer(className);\n\n        // Make the class public so we can call its static init converters from other packages\n        transformer.removeModifiers(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED);\n        transformer.addModifiers(Opcodes.ACC_PUBLIC);\n\n        // Get ClassInfo\n        ClassInfo classInfo = indexView.getClassByName(className.replace('/', '.'));\n        if (classInfo == null) {\n            throw new RuntimeException(\"ClassInfo not found for \" + className);\n        }\n\n        // Collect part types for multipart PartType parameters\n        LinkedHashMap<FieldInfo, ServerIndexedParameter> partTypes = new LinkedHashMap<>();\n        for (Entry<FieldInfo, ServerIndexedParameter> entry : fieldExtractors.entrySet()) {\n            FieldInfo fieldInfo = entry.getKey();\n            ServerIndexedParameter extractor = entry.getValue();\n            if (extractor.getType() == ParameterType.FORM) {\n                MultipartFormParamExtractor.Type multipartFormType = getMultipartFormType(extractor);\n                if (multipartFormType == MultipartFormParamExtractor.Type.PartType) {\n                    partTypes.put(fieldInfo, extractor);\n                }\n            }\n        }\n\n        // Add interface\n        if (!superTypeIsInjectable) {\n            transformer.addInterface(ResteasyReactiveInjectionTarget.class);","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/scanning/ClassInjectorTransformer.java#L81-L117","documentation":"During bytecode transformation for class-injected fields (RESTEasy Reactive's class injector optimization), ClassInjectorTransformer.apply needs the Jandex ClassInfo for the target class to read its metadata. If the index does not contain the class, transformation cannot proceed and a RuntimeException is thrown.","triggerScenarios":"Calling apply() with a className whose internal (slashed) name, after conversion to a dotted name, is absent from the IndexView used at build time — i.e. a class not covered by the application index.","commonSituations":"Classes generated by other build steps after indexing; classes from dependencies not included in the index; a stale/partial index in custom build-step code; typos in internal vs dotted class names.","solutions":["Ensure the class is part of the Jandex index — add its archive/location to indexed classes or re-run indexing after generation.","If the class is generated by an earlier build step, make sure your step is ordered after it (use @BuildStep(loads=...) / BuildProducer ordering).","Verify the className passed uses the internal slashed form that the transformer expects, since the code converts '/' to '.' before lookup.","If writing a custom extension, index additional classes via AdditionalClassesIndexBuildItem or register them for indexing."],"exampleFix":"// before\ntransformer.apply(\"com/example/Generated/Resource\"); // not indexed\n// after\n// produce an AdditionalClassesIndexBuildItem or ensure the class is written before indexing\nindexProducer.produceIndexFor(GeneratedResource.class);","handlingStrategy":"validation","validationCode":"ClassInfo info = indexView.getClassByName(className.replace('/', '.'));\nif (info == null) {\n    throw new IllegalStateException(\"Class \" + className + \" must be part of the Jandex index before injection transformation\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    transformer.apply(className);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"ClassInfo not found\")) {\n        throw new BuildException(\"Add \" + className + \" to the Jandex index (index the producing archive or order build steps)\", e);\n    }\n    throw e;\n}","preventionTips":["Ensure every class transformed at build time is produced before indexing or is explicitly added to the index.","Keep generated classes' build steps ordered before steps that transform them.","Use consistent internal-name conventions (slashed) when passing class names.","Run extension builds with index validation enabled to catch missing classes early."],"tags":["quarkus","resteasy-reactive","jandex","classindex","build-time"],"backgroundTag":"class-not-indexed","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"}