JakeWharton/butterknife · error · IllegalStateException
@BindInt field type must be 'int'. (
Error message
@BindInt field type must be 'int'. (
What it means
Thrown by the reflection-based ButterKnife runtime when a field annotated with @BindInt is not declared as primitive int. The binder resolves the integer resource with Resources.getInteger and only assigns to int.class; long, Integer, and float fields are rejected.
Source
Thrown at butterknife-reflect/src/main/java/butterknife/ButterKnife.java:627
return Unbinder.EMPTY;
}
private static @Nullable Unbinder parseBindInt(Object target, Field field, View source) {
BindInt bindInt = field.getAnnotation(BindInt.class);
if (bindInt == null) {
return null;
}
validateMember(field);
int id = bindInt.value();
Resources resources = source.getContext().getResources();
Class<?> fieldType = field.getType();
Object value;
if (fieldType == int.class) {
value = resources.getInteger(id);
} else {
throw new IllegalStateException("@BindInt field type must be 'int'. ("
+ field.getDeclaringClass().getName()
+ '.'
+ field.getName()
+ ')');
}
trySet(field, target, value);
return Unbinder.EMPTY;
}
private static @Nullable Unbinder parseBindString(Object target, Field field, View source) {
BindString bindString = field.getAnnotation(BindString.class);
if (bindString == null) {
return null;
}
validateMember(field);
int id = bindString.value();View on GitHub (pinned to fcdebedf32)
Solutions
- Change the field to primitive `int`.
- If a long/Integer is required downstream, keep the int field and convert after bind.
- For non-integer resources use @BindFloat/@BindDimen; for compile-time safety switch to butterknife-compiler.
Example fix
// before @BindInt(R.int.anim_duration_ms) Long durationMs; // after @BindInt(R.int.anim_duration_ms) int durationMs;
Defensive patterns
Strategy: type-guard
Validate before calling
for (Field f : targetClass.getDeclaredFields()) {
if (f.isAnnotationPresent(BindInt.class) && f.getType() != int.class) {
throw new IllegalStateException(f + " must be int");
}
} Type guard
static boolean isValidBindIntField(Field f) {
return !f.isAnnotationPresent(BindInt.class) || f.getType() == int.class;
} Prevention
- Use primitive `int`, never Integer/long.
- Reserve @BindInt for <integer> resources; @BindDimen/@BindFloat for others.
- Use butterknife-compiler to fail at compile time.
When it happens
Trigger: ButterKnife.bind(...) via butterknife-reflect on a class with `@BindInt(R.int.max_count) Integer maxCount;`, `@BindInt(R.int.max_count) long maxCount;`, or `@BindInt(R.int.max_count) float maxCount;`.
Common situations: Boxing the field for nullability or API models, widening to long for counters, or annotating a dimen/float resource with @BindInt by mistake. Compile-time binder (butterknife-compiler) rejects this during build; only the reflect artifact throws at bind time.
Related errors
- @BindDimen field type must be 'int' or 'float'. (
- @BindDrawable field type must be 'Drawable'. (
- @BindFloat field type must be 'float'. (
- @BindFont field type must be 'Typeface'. (
- @BindString field type must be 'String'. (
AI-assisted analysis of JakeWharton/butterknife@fcdebedf32 (2026-08-14).
Data as JSON: /api/errors/6069f09f0f649c27.
Report an issue: GitHub.