JakeWharton/butterknife · error · IllegalStateException
More than one bind annotation on
Error message
More than one bind annotation on
What it means
The reflective binder processes each declared field through parseBindView, parseBindBitmap, parseBindColor, and so on in sequence, counting how many unbinders were produced. More than one means the field carries multiple ButterKnife bind annotations (e.g. @BindView and @BindString together), which is ambiguous, so an IllegalStateException is thrown at bind time.
Source
Thrown at butterknife-reflect/src/main/java/butterknife/ButterKnife.java:189
if (unbinder != null) unbinders.add(unbinder);
unbinder = parseBindDrawable(target, field, source);
if (unbinder != null) unbinders.add(unbinder);
unbinder = parseBindFloat(target, field, source);
if (unbinder != null) unbinders.add(unbinder);
unbinder = parseBindFont(target, field, source);
if (unbinder != null) unbinders.add(unbinder);
unbinder = parseBindInt(target, field, source);
if (unbinder != null) unbinders.add(unbinder);
unbinder = parseBindString(target, field, source);
if (unbinder != null) unbinders.add(unbinder);
if (unbinders.size() - unbinderStartingSize > 1) {
throw new IllegalStateException(
"More than one bind annotation on " + targetClass.getName() + "." + field.getName());
}
}
for (Method method : targetClass.getDeclaredMethods()) {
Unbinder unbinder;
unbinder = parseOnCheckedChanged(target, method, source);
if (unbinder != null) unbinders.add(unbinder);
unbinder = parseOnClick(target, method, source);
if (unbinder != null) unbinders.add(unbinder);
unbinder = parseOnEditorAction(target, method, source);
if (unbinder != null) unbinders.add(unbinder);
unbinder = parseOnFocusChange(target, method, source);
if (unbinder != null) unbinders.add(unbinder);View on GitHub (pinned to fcdebedf32)
Solutions
- Inspect the field named in the message and delete all but one ButterKnife annotation
- If you need multiple values, split them into separate fields each with a single annotation
Example fix
// before @BindView(R.id.avatar) @BindBitmap(R.drawable.avatar) ImageView avatar; // after @BindView(R.id.avatar) ImageView avatar; @BindBitmap(R.drawable.avatar) Bitmap avatarBitmap;
Defensive patterns
Strategy: validation
Validate before calling
// Before bind, assert each field carries at most one ButterKnife annotation
for (Field f : target.getClass().getDeclaredFields()) {
int count = 0;
for (Annotation a : f.getAnnotations()) {
if (a.annotationType().getName().startsWith("butterknife.")) count++;
}
if (count > 1) throw new IllegalStateException("Multiple bind annotations on " + f);
} Prevention
- One ButterKnife annotation per field, always
- When changing a field's annotation, delete the old one in the same edit
- Enable IDE inspections for duplicate annotations
When it happens
Trigger: Stacking annotations on one field, such as @BindView(R.id.title) @BindString(R.string.title) TextView title; a quick-fix IDE action adding a second bind annotation without removing the first.
Common situations: Changing a field from one resource type to another (e.g. @BindBitmap to @BindView) and leaving both annotations; copy-paste of annotated fields.
Related errors
- must not be private.
- @BindView fields must extend from View or be an interface. (
- @BindViews List must have a generic component. (
- @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/dcfab13745f68e61.
Report an issue: GitHub.