JakeWharton/butterknife · error · IllegalStateException
View '{}' with ID {} for {} was of the wrong type. See cause
Error message
View '{}' with ID {} for {} was of the wrong type. See cause for more info. What it means
Thrown by Utils.castView when the view found for a bound ID exists but cannot be cast to the annotated field's type. The original ClassCastException is preserved as the cause; the message identifies the resource entry name, ID, and the binding target ('who') so you can compare XML vs Java types.
Source
Thrown at butterknife-runtime/src/main/java/butterknife/internal/Utils.java:105
+ id
+ " for "
+ who
+ " was not found. If this view is optional add '@Nullable' (fields) or '@Optional'"
+ " (methods) annotation.");
}
public static <T> T findRequiredViewAsType(View source, @IdRes int id, String who,
Class<T> cls) {
View view = findRequiredView(source, id, who);
return castView(view, id, who, cls);
}
public static <T> T castView(View view, @IdRes int id, String who, Class<T> cls) {
try {
return cls.cast(view);
} catch (ClassCastException e) {
String name = getResourceEntryName(view, id);
throw new IllegalStateException("View '"
+ name
+ "' with ID "
+ id
+ " for "
+ who
+ " was of the wrong type. See cause for more info.", e);
}
}
public static <T> T castParam(Object value, String from, int fromPos, String to, int toPos,
Class<T> cls) {
try {
return cls.cast(value);
} catch (ClassCastException e) {
throw new IllegalStateException("Parameter #"
+ (fromPos + 1)
+ " of method '"
+ fromView on GitHub (pinned to fcdebedf32)
Solutions
- Align the types: change the field type to the XML widget's class (or a supertype of it).
- Check for ID collisions across includes/merge and rename the duplicate ID.
- If polymorphism is expected (same ID different types across variants), bind to the common supertype (e.g. View or TextView).
Example fix
<!-- before --> <ImageView android:id="@+id/media" ... /> @BindView(R.id.media) TextView media; // wrong type <!-- after --> <ImageView android:id="@+id/media" ... /> @BindView(R.id.media) ImageView media;
Defensive patterns
Strategy: type-guard
Validate before calling
View v = sourceView.findViewById(R.id.media);
if (v != null && !TextView.class.isAssignableFrom(v.getClass())) {
// XML type differs from field type — fix layout or field before bind
} Type guard
static boolean viewMatchesFieldType(View v, Class<?> fieldType) {
return v == null || fieldType.isAssignableFrom(v.getClass());
} Prevention
- Keep XML widget types and Java field types aligned; bind to a common supertype where variants differ.
- Watch for duplicate IDs across include/merge — rename collisions.
- When swapping widgets in XML, grep Java/Kotlin for @BindView references to that ID.
When it happens
Trigger: `@BindView(R.id.title) TextView title;` where XML declares `<androidx.appcompat.widget.AppCompatEditText android:id="@id/title" ...>` — any mismatch between the XML widget class and the annotated field type, e.g. EditText vs TextView is fine (upcast) but TextView vs ImageView, or a custom view replaced by its subclass, throws.
Common situations: Renaming/replacing a widget in XML during a redesign while the Java field keeps the old type; merging layouts where an ID collides across include/merge tags; support-library migrations changing actual inflated classes; a wrong <include> bringing another layout's view with the same ID first in the hierarchy.
Related errors
- Required view '{}' with ID {} for {} was not found. If this
- @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'. (
AI-assisted analysis of JakeWharton/butterknife@fcdebedf32 (2026-08-14).
Data as JSON: /api/errors/3796e4b893cde0fb.
Report an issue: GitHub.