JakeWharton/butterknife · error · IllegalStateException
@BindFont field type must be 'Typeface'. (
Error message
@BindFont field type must be 'Typeface'. (
What it means
Thrown by the reflection-based ButterKnife runtime when a field annotated with @BindFont is not declared as android.graphics.Typeface. The binder can only produce a Typeface from the font resource; any other declared type (String, int, a custom font wrapper) fails the exact field.getType() == Typeface.class check.
Source
Thrown at butterknife-reflect/src/main/java/butterknife/ButterKnife.java:601
switch (style) {
case Typeface.NORMAL:
value = font;
break;
case Typeface.BOLD:
case Typeface.ITALIC:
case Typeface.BOLD_ITALIC:
value = Typeface.create(font, style);
break;
default:
throw new IllegalStateException(
"@BindFont style must be NORMAL, BOLD, ITALIC, or BOLD_ITALIC. ("
+ field.getDeclaringClass().getName()
+ '.'
+ field.getName()
+ ')');
}
} else {
throw new IllegalStateException("@BindFont field type must be 'Typeface'. ("
+ field.getDeclaringClass().getName()
+ '.'
+ field.getName()
+ ')');
}
trySet(field, target, value);
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();View on GitHub (pinned to fcdebedf32)
Solutions
- Declare the field as `Typeface` and apply it with view.setTypeface(...) afterwards.
- If a custom wrapper is needed, bind the Typeface field and construct the wrapper after bind.
- Move to butterknife-compiler for compile-time checking.
Example fix
// before @BindFont(R.font.titles) String titleFont; // after @BindFont(R.font.titles) Typeface titleFont; // then: textView.setTypeface(titleFont);
Defensive patterns
Strategy: type-guard
Validate before calling
for (Field f : targetClass.getDeclaredFields()) {
if (f.isAnnotationPresent(BindFont.class) && f.getType() != Typeface.class) {
throw new IllegalStateException(f + " must be Typeface");
}
} Type guard
static boolean isValidBindFontField(Field f) {
return !f.isAnnotationPresent(BindFont.class)
|| f.getType() == Typeface.class;
} Prevention
- Declare @BindFont fields as android.graphics.Typeface.
- Apply with textView.setTypeface(field) — never bind String or resource-id ints.
- Use butterknife-compiler for compile-time checks.
When it happens
Trigger: ButterKnife.bind(...) via butterknife-reflect on a class with `@BindFont(R.font.montserrat) String fontName;` or `@BindFont(R.font.montserrat) int fontResId;` — any field whose type is not exactly Typeface.
Common situations: Annotating a resource-id int field or a custom font-wrapper field instead of the Typeface field that is actually applied to views; mixing up @BindFont with a font-name String convention used elsewhere in the project. The compiler path reports this at compile time; reflect defers it to runtime.
Related errors
- @BindDimen field type must be 'int' or 'float'. (
- @BindDrawable field type must be 'Drawable'. (
- @BindFloat field type must be 'float'. (
- @BindFont style must be NORMAL, BOLD, ITALIC, or BOLD_ITALIC
- @BindInt field type must be 'int'. (
AI-assisted analysis of JakeWharton/butterknife@fcdebedf32 (2026-08-14).
Data as JSON: /api/errors/ae1e7cfa61e7ef2c.
Report an issue: GitHub.