{"record":{"id":"c6e0ba304e27650b","repo":"JakeWharton/butterknife","slug":"unable-to-invoke","errorCode":null,"errorMessage":"Unable to invoke {}","messagePattern":"Unable to invoke (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"butterknife/src/main/java/butterknife/ButterKnife.java","lineNumber":172,"sourceCode":"   *\n   * @param target Target class for view binding.\n   * @param source View root on which IDs will be looked up.\n   */\n  @NonNull @UiThread\n  public static Unbinder bind(@NonNull Object target, @NonNull View source) {\n    Class<?> targetClass = target.getClass();\n    if (debug) Log.d(TAG, \"Looking up binding for \" + targetClass.getName());\n    Constructor<? extends Unbinder> constructor = findBindingConstructorForClass(targetClass);\n\n    if (constructor == null) {\n      return Unbinder.EMPTY;\n    }\n\n    //noinspection TryWithIdenticalCatches Resolves to API 19+ only type.\n    try {\n      return constructor.newInstance(target, source);\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 create binding instance.\", cause);\n    }\n  }\n\n  @Nullable @CheckResult @UiThread\n  private static Constructor<? extends Unbinder> findBindingConstructorForClass(Class<?> cls) {\n    Constructor<? extends Unbinder> bindingCtor = BINDINGS.get(cls);\n    if (bindingCtor != null || BINDINGS.containsKey(cls)) {","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/JakeWharton/butterknife/blob/fcdebedf3276096db2f51bf6372b849b5a9c75ed/butterknife/src/main/java/butterknife/ButterKnife.java#L154-L190","documentation":"Thrown by the generated-binding path in ButterKnife.bind when constructing the target class's generated ViewBinding class fails reflectively with IllegalAccessException or InstantiationException (constructor.newInstance). This means the binding class was found but could not be instantiated/accessed — not that the @OnClick handler itself threw (InvocationTargetException is unwrapped separately, rethrowing its cause).","triggerScenarios":"ButterKnife.bind(activity/view/fragment) where the generated FooViewBinding class exists but its (target, source) constructor is not accessible or the class is abstract/instantiation-blocked — typically ProGuard/R8 renaming or stripping the binding class's constructor after the lookup step, or a stale/duplicated binding class on the classpath.","commonSituations":"Release builds with obfuscation and missing keep rules for *ViewBinding classes; incremental/instant-run classpath skew where an old binding class without the two-arg constructor is packaged; compiling with butterknife but running against a dex that kept only part of it; binding an inner class whose generated outer reference confuses the constructor lookup.","solutions":["Add keep rules: `-keep class **_ViewBinding { <init>(...); }` plus keep the annotated members, or use the shipped butterknife proguard rules (`-keep class **_ViewBinding*` guidance in the README).","Clean and rebuild (./gradlew clean assembleDebug) to eliminate stale generated classes on the classpath.","Verify butterknife-compiler matches the butterknife runtime version in dependencies; mismatched versions generate incompatible binding classes.","If it persists, check the cause chain — InstantiationException points to an abstract/interface binding class surviving from an old build, so delete old build/ artifacts."],"exampleFix":"# before: proguard-rules.pro missing butterknife keeps (release crash)\n# after\n-keep class **_ViewBinding { <init>(...); }\n-keepclasseswithmembernames class * { @butterknife.* <fields>; }\n-keepclasseswithmembernames class * { @butterknife.* <methods>; }","handlingStrategy":"try-catch","validationCode":"// Sanity check before relying on codegen in release builds\ntry {\n  Class.forName(targetClass.getName() + \"_ViewBinding\");\n} catch (ClassNotFoundException e) {\n  throw new IllegalStateException(\"Binding class missing — check butterknife-compiler/keeps\", e);\n}","typeGuard":null,"tryCatchPattern":"try {\n  unbinder = ButterKnife.bind(target, source);\n} catch (RuntimeException e) {\n  Throwable c = e.getCause();\n  if (c instanceof IllegalAccessException || c instanceof InstantiationException) {\n    // obfuscation/stale-classpath issue: report keep-rule/build problem\n    CrashReporter.log(\"ButterKnife codegen broken: \" + c);\n  }\n  throw e;\n}","preventionTips":["Ship butterknife keep rules in proguard-rules.pro for release builds.","Keep butterknife and butterknife-compiler versions in lockstep; clean build after upgrades.","Run a smoke test of every bound screen in an obfuscated release build before shipping."],"tags":["butterknife","codegen","reflection","proguard","instantiation","version-mismatch"],"backgroundTag":null,"analyzedSha":"fcdebedf3276096db2f51bf6372b849b5a9c75ed","analyzedAt":"2026-08-14T10:13:55.083Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}