JakeWharton/butterknife · error · IllegalStateException

@BindBool field type must be 'boolean'. (

Error message

@BindBool field type must be 'boolean'. (

What it means

@BindBool reads a boolean resource with Resources.getBoolean, so parseBindBool requires the field's type to be the primitive boolean. A Boolean (boxed), int, or any other type throws this IllegalStateException at bind time. The compiler flavor enforces the identical rule during annotation processing.

Solutions

  1. Change the field to primitive boolean: `@BindBool(R.bool.is_tablet) boolean isTablet;`
  2. In Kotlin, use a non-null `Boolean` property so the backing field is primitive

Example fix

// before
@BindBool(R.bool.is_tablet)
Boolean isTablet; // boxed

// after
@BindBool(R.bool.is_tablet)
boolean isTablet;
Defensive patterns

Strategy: type-guard

Validate before calling

if (field.getType() != boolean.class) {
  throw new IllegalStateException("@BindBool field must be primitive boolean: " + field);
}

Type guard

static boolean isPrimitiveBooleanField(Field f) {
  return f.getType() == boolean.class;
}

Prevention

When it happens

Trigger: `@BindBool(R.bool.is_tablet) Boolean isTablet;` (boxed wrapper instead of primitive); Kotlin properties whose backing field resolves to Boolean; annotating an int flag field with @BindBool.

Common situations: Kotlin `var isTablet: Boolean = false` with the annotation landing on a boxed context; Java developers using the wrapper type out of habit; nullable boolean fields.

Related errors


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

Appendix: source

Thrown at butterknife-reflect/src/main/java/butterknife/ButterKnife.java:446

    return Unbinder.EMPTY;
  }

  private static @Nullable Unbinder parseBindBool(Object target, Field field, View source) {
    BindBool bindBool = field.getAnnotation(BindBool.class);
    if (bindBool == null) {
      return null;
    }
    validateMember(field);

    int id = bindBool.value();
    Resources resources = source.getContext().getResources();

    Object value;
    Class<?> fieldType = field.getType();
    if (fieldType == boolean.class) {
      value = resources.getBoolean(id);
    } else {
      throw new IllegalStateException("@BindBool field type must be 'boolean'. ("
          + field.getDeclaringClass().getName()
          + '.'
          + field.getName()
          + ')');
    }
    trySet(field, target, value);

    return Unbinder.EMPTY;
  }

  private static @Nullable Unbinder parseBindColor(Object target, Field field, View source) {
    BindColor bindColor = field.getAnnotation(BindColor.class);
    if (bindColor == null) {
      return null;
    }
    validateMember(field);

    int id = bindColor.value();

View on GitHub (pinned to fcdebedf32)