JakeWharton/butterknife · error · IllegalStateException
Bindings already cleared.
Error message
Bindings already cleared.
What it means
Thrown by CompositeUnbinder.unbind() when unbind() is called more than once on the same binding. The composite nulls out its list of unbinders after the first unbind() and treats a second call as a programmer error (double-unbind), because views would be re-released after the target is already detached.
Source
Thrown at butterknife-reflect/src/main/java/butterknife/CompositeUnbinder.java:16
package butterknife;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.List;
final class CompositeUnbinder implements Unbinder {
private @Nullable List<Unbinder> unbinders;
CompositeUnbinder(@NonNull List<Unbinder> unbinders) {
this.unbinders = unbinders;
}
@Override public void unbind() {
if (unbinders == null) {
throw new IllegalStateException("Bindings already cleared.");
}
for (Unbinder unbinder : unbinders) {
unbinder.unbind();
}
unbinders = null;
}
}
View on GitHub (pinned to fcdebedf32)
Solutions
- Guard the call: keep the Unbinder in a field, null it after unbind(), and check for null before calling (`if (unbinder != null) { unbinder.unbind(); unbinder = null; }`).
- Unbind in exactly one lifecycle method — onDestroyView for fragments that bind in onCreateView.
- Remove duplicate unbind() calls in base classes, subclasses, and manual cleanup paths.
Example fix
// before
@Override public void onDestroyView() { unbinder.unbind(); }
@Override public void onDestroy() { unbinder.unbind(); } // throws second time
// after
@Override public void onDestroyView() {
if (unbinder != null) { unbinder.unbind(); unbinder = null; }
} Defensive patterns
Strategy: validation
Validate before calling
if (unbinder != null) {
unbinder.unbind();
unbinder = null; // guard set immediately after use
} Prevention
- Store the Unbinder in a field; null it immediately after unbind().
- Unbind exactly once — onDestroyView for fragments, onDestroy for activities.
- Audit base classes for duplicate unbind() calls.
When it happens
Trigger: Calling ButterKnife.unbind(target) (or the generated/reflect Unbinder's unbind()) twice on the same target — e.g. unbind() in both onDestroyView() and onDestroy(), or onDestroy() plus a manual cleanup path, or unbinding a field that a lifecycle callback also unbinds.
Common situations: Fragments with defensive cleanup in multiple lifecycle methods; base fragment classes that call unbind() while a subclass also does; rebinding-then-unbinding flows where the old Unbinder reference is kept and unbound again during onDestroy. Modern ButterKnife (8.x+) switched to requiring each Unbider to be unbound exactly once and made double-unbind this explicit IllegalStateException.
Related errors
- @%s's %s.%s missing @%s annotation.
- @%s annotation must be on a method.
- @%s annotation value() type not int[].
- No @%s defined on @%s.
- Multiple listener methods specified on @%s.
AI-assisted analysis of JakeWharton/butterknife@fcdebedf32 (2026-08-14).
Data as JSON: /api/errors/1e167cf5b52fb92c.
Report an issue: GitHub.