JakeWharton/butterknife · error · IllegalStateException

No @%s defined on @%s's %s.%s.

Error message

No @%s defined on @%s's %s.%s.

What it means

When a listener annotation uses the callbacks() shape, the processor reflectively reads the annotation's callback() attribute (an enum constant), looks up the enum constant's Field, and expects an @ListenerMethod annotation on it. If that specific constant lacks @ListenerMethod, this IllegalStateException is thrown. Unlike the BindingSet variant (which walks all constants when generating multi-callback binders), this fires while parsing the single callback the user actually selected.

Source

Thrown at butterknife-compiler/src/main/java/butterknife/compiler/ButterKnifeProcessor.java:1120

    ListenerMethod method;
    ListenerMethod[] methods = listener.method();
    if (methods.length > 1) {
      throw new IllegalStateException(String.format("Multiple listener methods specified on @%s.",
          annotationClass.getSimpleName()));
    } else if (methods.length == 1) {
      if (listener.callbacks() != ListenerClass.NONE.class) {
        throw new IllegalStateException(
            String.format("Both method() and callback() defined on @%s.",
                annotationClass.getSimpleName()));
      }
      method = methods[0];
    } else {
      Method annotationCallback = annotationClass.getDeclaredMethod("callback");
      Enum<?> callback = (Enum<?>) annotationCallback.invoke(annotation);
      Field callbackField = callback.getDeclaringClass().getField(callback.name());
      method = callbackField.getAnnotation(ListenerMethod.class);
      if (method == null) {
        throw new IllegalStateException(
            String.format("No @%s defined on @%s's %s.%s.", ListenerMethod.class.getSimpleName(),
                annotationClass.getSimpleName(), callback.getDeclaringClass().getSimpleName(),
                callback.name()));
      }
    }

    // Verify that the method has equal to or less than the number of parameters as the listener.
    List<? extends VariableElement> methodParameters = executableElement.getParameters();
    if (methodParameters.size() > method.parameters().length) {
      error(element, "@%s methods can have at most %s parameter(s). (%s.%s)",
          annotationClass.getSimpleName(), method.parameters().length,
          enclosingElement.getQualifiedName(), element.getSimpleName());
      hasError = true;
    }

    // Verify method return type matches the listener.
    TypeMirror returnType = executableElement.getReturnType();
    if (returnType instanceof TypeVariable) {

View on GitHub (pinned to fcdebedf32)

Solutions

  1. Add @ListenerMethod(name = ..., parameters = ...) to the enum constant named in the error message
  2. Annotate every constant in the enum so any callback selection is safe

Example fix

// before
enum Callback {
  @ListenerMethod(name = "onItemSelected", parameters = {AdapterView.class, View.class, int.class, long.class})
  ITEM_SELECTED,
  NOTHING_SELECTED // no annotation
}

// after
enum Callback {
  @ListenerMethod(name = "onItemSelected", parameters = {AdapterView.class, View.class, int.class, long.class})
  ITEM_SELECTED,
  @ListenerMethod(name = "onNothingSelected", parameters = {AdapterView.class})
  NOTHING_SELECTED
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the enum constant you select has metadata before using it
Field f = callback.getDeclaringClass().getField(callback.name());
if (f.getAnnotation(ListenerMethod.class) == null) {
  throw new IllegalStateException(callback + " lacks @ListenerMethod");
}

Prevention

When it happens

Trigger: A callbacks enum where the constant chosen via the annotation's callback() attribute (e.g. @OnItemSelected(callback = Callback.NOTHING_SELECTED)) is missing its @ListenerMethod annotation.

Common situations: Extending a copied callback enum with new constants and forgetting the annotation on some; referencing a constant that was added for internal purposes without binding metadata.

Related errors


AI-assisted analysis of JakeWharton/butterknife@fcdebedf32 (2026-08-14). Data as JSON: /api/errors/8ad0128eb0c5d120. Report an issue: GitHub.