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
- Change the field declaration to `int` (getDimensionPixelSize, dp-accurate pixel size) or `float` (getDimension, raw value).
- If the boxed type is intentional, keep an int/float field and assign it to the wrapper separately after bind.
- 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
- Always declare @BindDimen fields as primitive int or float — never boxed types.
- Prefer butterknife-compiler so this class of error fails at compile time.
- In Kotlin use `int`/`float` (not Int?/Float?/Double).
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
- @BindDrawable field type must be 'Drawable'. (
- @BindFloat field type must be 'float'. (
- @BindFont field type must be 'Typeface'. (
- @BindInt field type must be 'int'. (
- @BindString field type must be 'String'. (
AI-assisted analysis of JakeWharton/butterknife@fcdebedf32 (2026-08-14).
Data as JSON: /api/errors/3763b2b5f84d8b3d.
Report an issue: GitHub.