JakeWharton/butterknife · error · IllegalStateException
@BindFloat field type must be 'float'. (
Error message
@BindFloat field type must be 'float'. (
What it means
Thrown by the reflection-based ButterKnife runtime when a field annotated with @BindFloat is not declared as primitive float. The binder reads the resource with Utils.getFloat and can only assign a float; doubles, boxed Floats, and ints are all rejected by the exact field.getType() == float.class check.
Source
Thrown at butterknife-reflect/src/main/java/butterknife/ButterKnife.java:557
return Unbinder.EMPTY;
}
private static @Nullable Unbinder parseBindFloat(Object target, Field field, View source) {
BindFloat bindInt = field.getAnnotation(BindFloat.class);
if (bindInt == null) {
return null;
}
validateMember(field);
int id = bindInt.value();
Context context = source.getContext();
Class<?> fieldType = field.getType();
Object value;
if (fieldType == float.class) {
value = Utils.getFloat(context, id);
} else {
throw new IllegalStateException("@BindFloat field type must be 'float'. ("
+ field.getDeclaringClass().getName()
+ '.'
+ field.getName()
+ ')');
}
trySet(field, target, value);
return Unbinder.EMPTY;
}
private static @Nullable Unbinder parseBindFont(Object target, Field field, View source) {
BindFont bindFont = field.getAnnotation(BindFont.class);
if (bindFont == null) {
return null;
}
validateMember(field);
int id = bindFont.value();View on GitHub (pinned to fcdebedf32)
Solutions
- Change the field to primitive `float`.
- If double precision is required afterwards, keep the float field and copy into a double after bind.
- Use @BindInt for integer resources or switch to butterknife-compiler for compile-time validation.
Example fix
// before @BindFloat(R.dimen.aspect) Double aspect; // after @BindFloat(R.dimen.aspect) float aspect;
Defensive patterns
Strategy: type-guard
Validate before calling
for (Field f : targetClass.getDeclaredFields()) {
if (f.isAnnotationPresent(BindFloat.class) && f.getType() != float.class) {
throw new IllegalStateException(f + " must be float");
}
} Type guard
static boolean isValidBindFloatField(Field f) {
return !f.isAnnotationPresent(BindFloat.class) || f.getType() == float.class;
} Prevention
- Use primitive `float`, never Float or double.
- Remember @BindFloat requires a float-format resource (`<item format="float">`).
- Use butterknife-compiler to catch type mistakes at build time.
When it happens
Trigger: ButterKnife.bind(...) via butterknife-reflect on a class containing `@BindFloat(R.dimen.ratio) double ratio;`, `@BindFloat(R.dimen.ratio) Float ratio;`, or `@BindFloat(R.dimen.ratio) int ratio;`.
Common situations: Using double for precision math and expecting implicit widening, boxing the value for an ORM/JSON model, or annotating a resource that was assumed to be an integer. The annotation processor catches this at compile time; the reflect artifact (common in unit tests) defers it to runtime.
Related errors
- @BindDimen field type must be 'int' or 'float'. (
- @BindDrawable field type must be 'Drawable'. (
- @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/1eb949c0a1bcb849.
Report an issue: GitHub.