{"record":{"id":"19b02c3c111d1310","repo":"JakeWharton/butterknife","slug":"unable-to-invoke-on-with-arguments","errorCode":null,"errorMessage":"Unable to invoke  on  with arguments ","messagePattern":"Unable to invoke  on  with arguments ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"butterknife-reflect/src/main/java/butterknife/ButterKnife.java","lineNumber":1135,"sourceCode":"\n  static void trySet(Field field, Object target, @Nullable Object value) {\n    try {\n      field.set(target, value);\n    } catch (IllegalAccessException e) {\n      throw new RuntimeException(\"Unable to assign \" + value + \" to \" + field + \" on \" + target, e);\n    }\n  }\n\n  private static Object tryInvoke(Method method, Object target, Object... arguments) {\n    Throwable cause;\n    try {\n      return method.invoke(target, arguments);\n    } catch (IllegalAccessException e) {\n      cause = e;\n    } catch (InvocationTargetException e) {\n      cause = e;\n    }\n    throw new RuntimeException(\n        \"Unable to invoke \" + method + \" on \" + target + \" with arguments \"\n            + Arrays.toString(arguments), cause);\n  }\n\n  private static final Setter<CompoundButton, CompoundButton.OnCheckedChangeListener>\n      ON_CHECKED_CHANGE = (view, value, index) -> view.setOnCheckedChangeListener(value);\n  private static final Setter<View, View.OnClickListener> ON_CLICK =\n      (view, value, index) -> view.setOnClickListener(value);\n  private static final Setter<TextView, TextView.OnEditorActionListener> ON_EDITOR_ACTION =\n      (view, value, index) -> view.setOnEditorActionListener(value);\n  private static final Setter<View, View.OnFocusChangeListener> ON_FOCUS_CHANGE =\n      (view, value, index) -> view.setOnFocusChangeListener(value);\n  private static final Setter<AdapterView<?>, AdapterView.OnItemClickListener> ON_ITEM_CLICK =\n      (view, value, index) -> view.setOnItemClickListener(value);\n  private static final Setter<AdapterView<?>, AdapterView.OnItemLongClickListener>\n      ON_ITEM_LONG_CLICK = (view, value, index) -> view.setOnItemLongClickListener(value);\n  private static final Setter<View, View.OnLongClickListener> ON_LONG_CLICK =\n      (view, value, index) -> view.setOnLongClickListener(value);","sourceCodeStart":1117,"sourceCodeEnd":1153,"githubUrl":"https://github.com/JakeWharton/butterknife/blob/fcdebedf3276096db2f51bf6372b849b5a9c75ed/butterknife-reflect/src/main/java/butterknife/ButterKnife.java#L1117-L1153","documentation":"Wrapped in a RuntimeException and rethrown by ButterKnife's reflect binder (tryInvoke) when Method.invoke fails with IllegalAccessException or InvocationTargetException during listener registration/proxy invocation. The message names the method, target, and arguments; the cause holds the underlying failure.","triggerScenarios":"ButterKnife.bind(...) via butterknife-reflect when invoking an @OnClick/@On* method fails reflectively: the method became inaccessible (ProGuard renamed/removed it, setAccessible blocked), or the proxy invocation threw a checked exception not declared by the method.","commonSituations":"Obfuscated release builds where the annotation survives but the method does not; listener callbacks running on a different thread hitting access checks; handler methods whose bodies throw (the InvocationTargetException case) — e.g. an @OnClick that dereferences a null bundled extra. Distinct from the normal case where a listener's own exception propagates: this wrapper means the reflective call itself could not complete.","solutions":["Inspect the cause: if InvocationTargetException wraps an NPE/IllegalState from the handler body, fix that exception at its source.","Add ProGuard keep rules (`-keepclassmembers class ** { @butterknife.* <methods>; }`) or switch to butterknife-compiler which needs no reflection.","Ensure listener methods are non-private, non-static, and not renamed by build tooling."],"exampleFix":"# before (proguard-rules.pro has no keeps, reflect binder)\n# after\n-keep class **_ViewBinding { *; }\n-keepclassmembers class ** {\n  @butterknife.* <methods>;\n  @butterknife.* <fields>;\n}","handlingStrategy":"try-catch","validationCode":"int m = method.getModifiers();\nif ((m & (Modifier.PRIVATE | Modifier.STATIC)) != 0) {\n  throw new IllegalStateException(method + \" not reflectively invocable\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  ButterKnife.bind(target, source);\n} catch (RuntimeException e) {\n  Throwable c = e.getCause();\n  if (c instanceof InvocationTargetException && c.getCause() != null) {\n    throw new RuntimeException(\"Handler threw: \" + c.getCause(), c.getCause());\n  }\n  throw e;\n}","preventionTips":["Keep @On* methods non-private and non-static; add ProGuard keeps for them.","If the cause is InvocationTargetException, the real bug is inside your handler body — debug that.","Use butterknife-compiler to eliminate reflective invocation entirely."],"tags":["butterknife","reflection","method-invocation","proguard","listener"],"backgroundTag":null,"analyzedSha":"fcdebedf3276096db2f51bf6372b849b5a9c75ed","analyzedAt":"2026-08-14T10:13:55.083Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}