JakeWharton/butterknife · error · IllegalStateException

@BindDimen field type must be 'int' or 'float'. (

Error message

@BindDimen field type must be 'int' or 'float'. (

What it means

Thrown by the reflection-based ButterKnife runtime when a field annotated with @BindDimen is declared with a type other than int or float. The reflect binder inspects field.getType() at bind time and only knows how to produce a dimension pixel size (int) or a raw dimension (float); any other declared type is a programming error in the annotated class.

Source

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

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

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

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

    return Unbinder.EMPTY;
  }

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

    int id = bindDrawable.value();

View on GitHub (pinned to fcdebedf32)

Solutions

  1. Change the field declaration to `int` (getDimensionPixelSize, dp-accurate pixel size) or `float` (getDimension, raw value).
  2. If the boxed type is intentional, keep an int/float field and assign it to the wrapper separately after bind.
  3. Switch from butterknife-reflect to butterknife-compiler so this mistake fails at compile time instead of runtime.

Example fix

// before
@BindDimen(R.dimen.activity_margin) Long margin;

// after
@BindDimen(R.dimen.activity_margin) float margin;
Defensive patterns

Strategy: type-guard

Validate before calling

// Before bind: assert every @BindDimen field is int or float
for (Field f : targetClass.getDeclaredFields()) {
  if (f.isAnnotationPresent(BindDimen.class)) {
    Class<?> t = f.getType();
    if (t != int.class && t != float.class) {
      throw new IllegalStateException(f + " must be int or float");
    }
  }
}

Type guard

static boolean isValidBindDimenField(Field f) {
  if (!f.isAnnotationPresent(BindDimen.class)) return true;
  Class<?> t = f.getType();
  return t == int.class || t == float.class;
}

Prevention

When it happens

Trigger: Calling ButterKnife.bind(target, source) (butterknife-reflect) on a class that has a field like `@BindDimen(R.dimen.foo) long dimen;` or `@BindDimen(R.dimen.foo) Double dimen;` — i.e. the declared field type is not exactly int.class or float.class (boxed types also fail).

Common situations: Developer boxes the primitive (Integer/Double/Float), uses long for large dimensions, or copies a @BindDimen declaration onto an existing field of a wider type during refactoring. Note the annotation processor (butterknife-compiler) rejects this at compile time, so it appears only when using the butterknife-reflect artifact (e.g. in unit tests or instant-run setups).

Related errors


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