JakeWharton/butterknife · error · IllegalStateException
@BindViews List must have a generic component. (
Error message
@BindViews List must have a generic component. (
What it means
parseBindViews accepts a List field only if its generic type is a parameterized type, so it can extract the component (element) view class from the type argument. A raw `List` (or a List whose generic info is erased/unavailable at reflection time) leaves no component class, so bind throws this IllegalStateException.
Source
Thrown at butterknife-reflect/src/main/java/butterknife/ButterKnife.java:284
BindViews bindViews = field.getAnnotation(BindViews.class);
if (bindViews == null) {
return null;
}
validateMember(field);
Class<?> fieldClass = field.getType();
Class<?> viewClass;
boolean isArray = fieldClass.isArray();
if (isArray) {
viewClass = fieldClass.getComponentType();
} else if (fieldClass == List.class) {
Type fieldType = field.getGenericType();
if (fieldType instanceof ParameterizedType) {
Type viewType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
// TODO real rawType impl!!!!
viewClass = (Class<?>) viewType;
} else {
throw new IllegalStateException("@BindViews List must have a generic component. ("
+ field.getDeclaringClass().getName()
+ '.'
+ field.getName()
+ ')');
}
} else {
throw new IllegalStateException("@BindViews must be a List or array. ("
+ field.getDeclaringClass().getName()
+ '.'
+ field.getName()
+ ')');
}
if (!View.class.isAssignableFrom(viewClass) && !viewClass.isInterface()) {
throw new IllegalStateException(
"@BindViews List or array type must extend from View or be an interface. ("
+ field.getDeclaringClass().getName()
+ '.'
+ field.getName()View on GitHub (pinned to fcdebedf32)
Solutions
- Parameterize the field: `@BindViews({...}) List<TextView> textViews;`
- If you cannot use generics, switch to a typed array: `@BindViews({...}) TextView[] textViews;`
Example fix
// before
@BindViews({R.id.first, R.id.second})
List labels; // raw List
// after
@BindViews({R.id.first, R.id.second})
List<TextView> labels; Defensive patterns
Strategy: type-guard
Validate before calling
if (field.getType() == List.class
&& !(field.getGenericType() instanceof ParameterizedType)) {
throw new IllegalStateException("Raw List for @BindViews: " + field);
} Type guard
static boolean isParameterizedList(Field f) {
return f.getType() == List.class
&& f.getGenericType() instanceof ParameterizedType;
} Prevention
- Always declare @BindViews fields as List<SomeView> or SomeView[]
- Treat raw-type compiler warnings as errors in ButterKnife-using modules
When it happens
Trigger: Declaring `@BindViews({R.id.a, R.id.b}) List views;` without a type argument; using a raw List type from a pre-generics codebase or an unchecked cast that erases the parameterization.
Common situations: Old Java 1.4-style code reused with ButterKnife; IDE warnings about raw types ignored; fields typed as List after refactoring away the generic parameter.
Related errors
- must not be private.
- More than one bind annotation on
- @BindView fields must extend from View or be an interface. (
- @BindViews must be a List or array. (
- @BindViews List or array type must extend from View or be an
AI-assisted analysis of JakeWharton/butterknife@fcdebedf32 (2026-08-14).
Data as JSON: /api/errors/ef3da7a99feb2f2e.
Report an issue: GitHub.