{"record":{"id":"1e0a313d9b4f9d52","repo":"airbnb/epoxy","slug":"unable-to-invoke-constructor","errorCode":null,"errorMessage":"Unable to invoke {constructor}","messagePattern":"Unable to invoke (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"epoxy-adapter/src/main/java/com/airbnb/epoxy/ControllerHelperLookup.java","lineNumber":29,"sourceCode":" * Looks up a generated {@link ControllerHelper} implementation for a given adapter.\n * If the adapter has no {@link com.airbnb.epoxy.AutoModel} models then a No-Op implementation will\n * be returned.\n */\nclass ControllerHelperLookup {\n  private static final String GENERATED_HELPER_CLASS_SUFFIX = \"_EpoxyHelper\";\n  private static final Map<Class<?>, Constructor<?>> BINDINGS = new LinkedHashMap<>();\n  private static final NoOpControllerHelper NO_OP_CONTROLLER_HELPER = new NoOpControllerHelper();\n\n  static ControllerHelper getHelperForController(EpoxyController controller) {\n    Constructor<?> constructor = findConstructorForClass(controller.getClass());\n    if (constructor == null) {\n      return NO_OP_CONTROLLER_HELPER;\n    }\n\n    try {\n      return (ControllerHelper) constructor.newInstance(controller);\n    } catch (IllegalAccessException e) {\n      throw new RuntimeException(\"Unable to invoke \" + constructor, e);\n    } catch (InstantiationException e) {\n      throw new RuntimeException(\"Unable to invoke \" + constructor, e);\n    } catch (InvocationTargetException e) {\n      Throwable cause = e.getCause();\n      if (cause instanceof RuntimeException) {\n        throw (RuntimeException) cause;\n      }\n      if (cause instanceof Error) {\n        throw (Error) cause;\n      }\n      throw new RuntimeException(\"Unable to get Epoxy helper class.\", cause);\n    }\n  }\n\n  @Nullable\n  private static Constructor<?> findConstructorForClass(Class<?> controllerClass) {\n    Constructor<?> helperCtor = BINDINGS.get(controllerClass);\n    if (helperCtor != null || BINDINGS.containsKey(controllerClass)) {","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/airbnb/epoxy/blob/e45bd3a61fe3a1f130e184f5b8dcf172ab99025a/epoxy-adapter/src/main/java/com/airbnb/epoxy/ControllerHelperLookup.java#L11-L47","documentation":"ControllerHelperLookup generates/looks up a generated helper class for each EpoxyController and instantiates it reflectively via Constructor.newInstance(controller). If the reflective call fails with IllegalAccessException or InstantiationException, the library wraps it in a RuntimeException('Unable to invoke <constructor>').","triggerScenarios":"The generated helper class exists but its constructor cannot be invoked: constructor not accessible (non-public generated class/constructor with setAccessible failing under module/visibility restrictions), abstract or interface controller class, or constructor signature mismatch.","commonSituations":"Kotlin/Java visibility or obfuscation (ProGuard/R8 renaming or stripping the generated constructor); running on a classpath where the annotation processor output is stale or missing so the found class doesn't match the controller; instantiating an abstract controller.","solutions":["Check ProGuard/R8 keep rules for generated epoxy classes (-keep class **_EpoxyHelper { *; } or similar) so the constructor survives obfuscation.","Run a clean build so generated helper classes match the current controller code.","Ensure the controller is a concrete (non-abstract) class.","Verify the epoxy-compiler annotation processor is applied and its version matches epoxy-adapter."],"exampleFix":"// before\n// proguard-rules.pro missing epoxy rules -> generated constructor stripped\n\n// after\n-keep class **_EpoxyHelper { *; }\n-keep class com.airbnb.epoxy.** { *; }","handlingStrategy":"try-catch","validationCode":"// build-time: ensure epoxy-compiler is applied and keep rules exist\n// -keep class **_EpoxyHelper { <init>(...); }","typeGuard":null,"tryCatchPattern":"try { ControllerHelper h = ControllerHelperLookup.getHelperForController(controller); } catch (RuntimeException e) { throw new IllegalStateException(\"Epoxy helper init failed for \" + controller.getClass(), e.getCause()); }","preventionTips":["Add ProGuard/R8 keep rules for *_EpoxyHelper classes.","Match epoxy-compiler and epoxy-adapter versions.","Clean build after controller renames.","Avoid abstract controllers at helper lookup time."],"tags":["android","epoxy","reflection","code-generation","proguard"],"backgroundTag":"module-init-failed","analyzedSha":"e45bd3a61fe3a1f130e184f5b8dcf172ab99025a","analyzedAt":"2026-09-13T03:24:16.052Z","contentChangedAt":"2026-09-13T03:24:16.052Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}