{"record":{"id":"253d150eab61df64","repo":"JakeWharton/butterknife","slug":"both-method-and-callback-defined-on-s","errorCode":null,"errorMessage":"Both method() and callback() defined on @%s.","messagePattern":"Both method\\(\\) and callback\\(\\) defined on @(.+?)\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"butterknife-compiler/src/main/java/butterknife/compiler/ButterKnifeProcessor.java","lineNumber":1109,"sourceCode":"            hasError = true;\n          }\n        } else {\n          error(element, \"@%s annotation contains invalid ID %d. (%s.%s)\",\n              annotationClass.getSimpleName(), id, enclosingElement.getQualifiedName(),\n              element.getSimpleName());\n          hasError = true;\n        }\n      }\n    }\n\n    ListenerMethod method;\n    ListenerMethod[] methods = listener.method();\n    if (methods.length > 1) {\n      throw new IllegalStateException(String.format(\"Multiple listener methods specified on @%s.\",\n          annotationClass.getSimpleName()));\n    } else if (methods.length == 1) {\n      if (listener.callbacks() != ListenerClass.NONE.class) {\n        throw new IllegalStateException(\n            String.format(\"Both method() and callback() defined on @%s.\",\n                annotationClass.getSimpleName()));\n      }\n      method = methods[0];\n    } else {\n      Method annotationCallback = annotationClass.getDeclaredMethod(\"callback\");\n      Enum<?> callback = (Enum<?>) annotationCallback.invoke(annotation);\n      Field callbackField = callback.getDeclaringClass().getField(callback.name());\n      method = callbackField.getAnnotation(ListenerMethod.class);\n      if (method == null) {\n        throw new IllegalStateException(\n            String.format(\"No @%s defined on @%s's %s.%s.\", ListenerMethod.class.getSimpleName(),\n                annotationClass.getSimpleName(), callback.getDeclaringClass().getSimpleName(),\n                callback.name()));\n      }\n    }\n\n    // Verify that the method has equal to or less than the number of parameters as the listener.","sourceCodeStart":1091,"sourceCodeEnd":1127,"githubUrl":"https://github.com/JakeWharton/butterknife/blob/fcdebedf3276096db2f51bf6372b849b5a9c75ed/butterknife-compiler/src/main/java/butterknife/compiler/ButterKnifeProcessor.java#L1091-L1127","documentation":"@ListenerClass declares both method() (a default single @ListenerMethod) and callbacks() (an enum of per-constant @ListenerMethod annotations). The processor requires that when method() has exactly one entry, callbacks() must remain the NONE sentinel; any other callbacks class while method() is populated throws this IllegalStateException at processing time. The two mechanisms are mutually exclusive.","triggerScenarios":"Writing @ListenerClass(method = @ListenerMethod(...), callbacks = MyCallback.class) on a custom listener annotation — filling in both attributes.","commonSituations":"Starting from a method-based definition and later adding a callbacks enum (or vice versa) without clearing the other attribute; template code that pre-fills both.","solutions":["Remove the method() attribute so the callbacks() enum drives binding","Or reset callbacks to the default by deleting the callbacks attribute if the single method() entry is what you want"],"exampleFix":"// before\n@ListenerClass(\n    method = @ListenerMethod(name = \"onClick\", parameters = {View.class}),\n    callbacks = Callback.class)\npublic @interface OnThing { ... }\n\n// after\n@ListenerClass(callbacks = Callback.class)\npublic @interface OnThing { ... }","handlingStrategy":"validation","validationCode":"ListenerClass lc = OnCustomEvent.class.getAnnotation(ListenerClass.class);\nif (lc.method().length == 1 && lc.callbacks() != ListenerClass.NONE.class) {\n  throw new IllegalStateException(\"method() and callbacks() are mutually exclusive\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Fill in either method() or callbacks() on @ListenerClass, never both","Keep a single canonical template for custom listener annotations"],"tags":["butterknife","annotation-processing","listener","contract"],"backgroundTag":null,"analyzedSha":"fcdebedf3276096db2f51bf6372b849b5a9c75ed","analyzedAt":"2026-08-14T10:13:55.083Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}