{"record":{"id":"cb5d9eefd2474758","repo":"JakeWharton/butterknife","slug":"unable-to-match-class-method-method-arguments","errorCode":null,"errorMessage":"Unable to match <class>.<method> method arguments.\\n\\n  Parameter #N: <type>\\n    did not match any listener parameters\\n\\nMethods may have up to N parameter(s):\\n\\n  <callbackParameterTypes>\\n\\nThese may be listed in any order but will be searched for from top to bottom.","messagePattern":"Unable to match <class>\\.<method> method arguments\\.\\\\n\\\\n  Parameter #N: <type>\\\\n    did not match any listener parameters\\\\n\\\\nMethods may have up to N parameter\\(s\\):\\\\n\\\\n  <callbackParameterTypes>\\\\n\\\\nThese may be listed in any order but will be searched for from top to bottom\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"butterknife-reflect/src/main/java/butterknife/ButterKnife.java","lineNumber":1093,"sourceCode":"            .append(\"\\n    \");\n        if (i < targetIndex) {\n          builder.append(\"matched listener parameter #\")\n              .append(indexMap[i])\n              .append(\": \")\n              .append(callbackParameterTypes[indexMap[i]].getName());\n        } else {\n          builder.append(\"did not match any listener parameters\");\n        }\n      }\n      builder.append(\"\\n\\nMethods may have up to \")\n          .append(callbackParameterLength)\n          .append(\" parameter(s):\\n\");\n      for (Class<?> callbackParameter : callbackParameterTypes) {\n        builder.append(\"\\n  \").append(callbackParameter.getName());\n      }\n      builder.append(\n          \"\\n\\nThese may be listed in any order but will be searched for from top to bottom.\");\n      throw new IllegalStateException(builder.toString());\n    }\n\n    return new ArgumentTransformer() {\n      @Override public Object[] transform(Object... arguments) {\n        Object[] newArguments = new Object[indexMap.length];\n        for (int i = 0; i < indexMap.length; i++) {\n          newArguments[i] = arguments[indexMap[i]];\n        }\n        return newArguments;\n      }\n\n      @Override public String toString() {\n        StringBuilder builder = new StringBuilder(\"ArgumentTransformer[\");\n        for (int i = 0; i < indexMap.length; i++) {\n          if (i > 0) {\n            builder.append(\", \");\n          }\n          builder.append(i).append(\" => \").append(indexMap[i]);","sourceCodeStart":1075,"sourceCodeEnd":1111,"githubUrl":"https://github.com/JakeWharton/butterknife/blob/fcdebedf3276096db2f51bf6372b849b5a9c75ed/butterknife-reflect/src/main/java/butterknife/ButterKnife.java#L1075-L1111","documentation":"Thrown by ButterKnife's reflection binder when none of an @On* method's parameters can be matched by type to the wrapped listener callback's parameters. ButterKnife builds a map from each method parameter to a compatible callback parameter (searched top to bottom); if any parameter finds no match, binding aborts with a diagnostic listing the method's parameters, the available callback parameters, and the parameter count limit.","triggerScenarios":"ButterKnife.bind(...) via butterknife-reflect where a listener method's parameters are not assignable from the callback's parameter types — e.g. `@OnTextChanged(R.id.field) void text(String s)` while TextWatcher passes (CharSequence, int, int, int), or `@OnItemClick void item(int position)` where the callback supplies an AdapterView and View but no int.","commonSituations":"Assuming ButterKnife injects arbitrary values (positions, ids, ints) instead of only the actual callback arguments; using String where the callback gives CharSequence; reordering/renaming parameters during refactoring. Compile-time binder reports the equivalent error at build time; the reflect path surfaces it at runtime with this message.","solutions":["Read the message: make each method parameter's type assignable from the corresponding callback parameter (e.g. CharSequence not String for @OnTextChanged).","Drop parameters you do not need — ButterKnife allows any subset up to the callback's count.","Prefer butterknife-compiler so mismatches fail at compile time."],"exampleFix":"// before\n@OnTextChanged(R.id.query) void onQuery(String text) { }\n\n// after\n@OnTextChanged(R.id.query) void onQuery(CharSequence text) { }","handlingStrategy":"validation","validationCode":"// Ensure every parameter is assignable from some callback parameter\nClass<?>[] cb = {CharSequence.class, int.class, int.class, int.class}; // TextWatcher\nouter:\nfor (Class<?> p : method.getParameterTypes()) {\n  for (Class<?> c : cb) {\n    if (c.isAssignableFrom(p) || p.isAssignableFrom(c)) continue outer;\n  }\n  throw new IllegalStateException(\"No listener parameter matches \" + p);\n}","typeGuard":"static boolean paramMatchesCallback(Class<?> param, Class<?>[] callbackParams) {\n  for (Class<?> c : callbackParams) {\n    if (c.isAssignableFrom(param)) return true; // param can receive c\n  }\n  return false;\n}","tryCatchPattern":null,"preventionTips":["Use supertypes of callback parameters (CharSequence over String, View over Button).","Omit parameters you do not need instead of inventing values.","Read the thrown message: it lists the acceptable callback parameter types verbatim."],"tags":["butterknife","reflection","listener","parameters","type-mismatch"],"backgroundTag":null,"analyzedSha":"fcdebedf3276096db2f51bf6372b849b5a9c75ed","analyzedAt":"2026-08-14T10:13:55.083Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}