quarkusio/quarkus · error · IllegalArgumentException
A context class must be a public non-abstract top-level or s
Error message
A context class must be a public non-abstract top-level or static nested class
What it means
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.
Source
Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ContextConfigurator.java:116
* By default, the context is considered normal if the scope annotion is annotated with {@link NormalScope}.
* <p>
* It is possible to change this behavior. However, in such case the registrator is responsible for the correct
* implementation of {@link InjectableContext#isNormal()}.
*
* @return self
*/
public ContextConfigurator normal(boolean value) {
this.isNormal = value;
return this;
}
public ContextConfigurator contextClass(Class<? extends InjectableContext> contextClazz) {
if (!Modifier.isPublic(contextClazz.getModifiers())
|| Modifier.isAbstract(contextClazz.getModifiers())
|| contextClazz.isAnonymousClass()
|| contextClazz.isLocalClass()
|| (contextClazz.getEnclosingClass() != null && !Modifier.isStatic(contextClazz.getModifiers()))) {
throw new IllegalArgumentException(
"A context class must be a public non-abstract top-level or static nested class");
}
Constructor<?> constructor = getConstructor(contextClazz);
if (constructor == null) {
throw new IllegalArgumentException(
"A context class must either declare a no-args constructor or a constructor that accepts a single parameter of type io.quarkus.arc.CurrentContextFactory");
}
return creator(cg -> {
BlockCreator bc = cg.method();
List<Expr> args = constructor.getParameterCount() == 0 ? List.of() : List.of(cg.currentContextFactory());
return bc.new_(ConstructorDesc.of(constructor), args);
});
}
private Constructor<?> getConstructor(Class<? extends InjectableContext> contextClazz) {
Constructor<?> constructor = null;
try {View on GitHub (pinned to e1c734241f)
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
Example fix
// before
public class App { class MyContext extends RequestContext {} }
// after
public class App { public static class MyContext extends RequestContext {} } Defensive patterns
Strategy: validation
Validate before calling
static void validateContextClass(Class<? extends InjectableContext> c) {
int m = c.getModifiers();
if (!Modifier.isPublic(m) || Modifier.isAbstract(m) || c.isAnonymousClass() || c.isLocalClass()
|| (c.getEnclosingClass() != null && !Modifier.isStatic(m)))
throw new IllegalArgumentException("Invalid context class: " + c);
} Type guard
static boolean isValidContextClass(Class<?> c) {
int m = c.getModifiers();
return Modifier.isPublic(m) && !Modifier.isAbstract(m) && !c.isAnonymousClass()
&& !c.isLocalClass() && (c.getEnclosingClass() == null || Modifier.isStatic(m));
} Prevention
- Always declare custom contexts as public top-level or public static nested classes
- Never make context classes abstract or anonymous
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- A context class must either declare a no-args constructor or
- Quarkus does not support CDI Full @Specializes annotation; t
- IllegalStateException wrapping ClassNotFoundException for ge
- Unable to derive the logger name at ${injectionPoint}
- Improper integration of '${LogFilterFactory.class.getName()}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/5a635723614f0b66.
Report an issue: GitHub.