{"record":{"id":"5a635723614f0b66","repo":"quarkusio/quarkus","slug":"a-context-class-must-be-a-public-non-abstract-top","errorCode":null,"errorMessage":"A context class must be a public non-abstract top-level or static nested class","messagePattern":"A context class must be a public non-abstract top-level or static nested class","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ContextConfigurator.java","lineNumber":116,"sourceCode":"     * By default, the context is considered normal if the scope annotion is annotated with {@link NormalScope}.\n     * <p>\n     * It is possible to change this behavior. However, in such case the registrator is responsible for the correct\n     * implementation of {@link InjectableContext#isNormal()}.\n     *\n     * @return self\n     */\n    public ContextConfigurator normal(boolean value) {\n        this.isNormal = value;\n        return this;\n    }\n\n    public ContextConfigurator contextClass(Class<? extends InjectableContext> contextClazz) {\n        if (!Modifier.isPublic(contextClazz.getModifiers())\n                || Modifier.isAbstract(contextClazz.getModifiers())\n                || contextClazz.isAnonymousClass()\n                || contextClazz.isLocalClass()\n                || (contextClazz.getEnclosingClass() != null && !Modifier.isStatic(contextClazz.getModifiers()))) {\n            throw new IllegalArgumentException(\n                    \"A context class must be a public non-abstract top-level or static nested class\");\n        }\n        Constructor<?> constructor = getConstructor(contextClazz);\n        if (constructor == null) {\n            throw new IllegalArgumentException(\n                    \"A context class must either declare a no-args constructor or a constructor that accepts a single parameter of type io.quarkus.arc.CurrentContextFactory\");\n        }\n        return creator(cg -> {\n            BlockCreator bc = cg.method();\n\n            List<Expr> args = constructor.getParameterCount() == 0 ? List.of() : List.of(cg.currentContextFactory());\n            return bc.new_(ConstructorDesc.of(constructor), args);\n        });\n    }\n\n    private Constructor<?> getConstructor(Class<? extends InjectableContext> contextClazz) {\n        Constructor<?> constructor = null;\n        try {","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ContextConfigurator.java#L98-L134","documentation":"When registering a custom CDI context programmatically via ContextConfigurator.contextClass(), Arc validates the class is public, non-abstract, not anonymous/local, and if nested, static. Illegal shapes would make instantiating the context in generated bytecode impossible, so an IllegalArgumentException is thrown at registration time.","triggerScenarios":"Calling ArCContexts/register API with a context class that is package-private, abstract, an inner (non-static) class, an anonymous class, or a local class.","commonSituations":"Declaring the custom context as a non-static inner class of the test or application class; making the context package-private for 'encapsulation'; using a lambda-style anonymous subclass.","solutions":["Make the context class public","Remove abstract modifier or subclass it concretely","Mark the nested class static (or move it to top level)","Ensure it is a named class, not anonymous/local"],"exampleFix":"// before\npublic class App { class MyContext extends RequestContext {} }\n// after\npublic class App { public static class MyContext extends RequestContext {} }","handlingStrategy":"validation","validationCode":"static void validateContextClass(Class<? extends InjectableContext> c) {\n  int m = c.getModifiers();\n  if (!Modifier.isPublic(m) || Modifier.isAbstract(m) || c.isAnonymousClass() || c.isLocalClass()\n      || (c.getEnclosingClass() != null && !Modifier.isStatic(m)))\n    throw new IllegalArgumentException(\"Invalid context class: \" + c);\n}","typeGuard":"static boolean isValidContextClass(Class<?> c) {\n  int m = c.getModifiers();\n  return Modifier.isPublic(m) && !Modifier.isAbstract(m) && !c.isAnonymousClass()\n      && !c.isLocalClass() && (c.getEnclosingClass() == null || Modifier.isStatic(m));\n}","tryCatchPattern":null,"preventionTips":["Always declare custom contexts as public top-level or public static nested classes","Never make context classes abstract or anonymous"],"tags":["quarkus","arc","cdi","custom-context","validation"],"backgroundTag":"invalid-custom-context-class","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"}