JakeWharton/butterknife · error · RuntimeException
Unable to create binding instance.
Error message
Unable to create binding instance.
What it means
ButterKnife reflectively invoked the generated binding constructor and the constructor threw an exception whose cause is neither a RuntimeException nor an Error (i.e. a checked exception). Because checked exceptions cannot legally escape the reflective call site, ButterKnife wraps the cause in this generic RuntimeException. In practice the cause is almost never thrown by ButterKnife itself; generated constructors only throw IllegalStateException (a RuntimeException, which is rethrown unwrapped at line 178), so a checked cause points to user code reached from the constructor, such as an @OnClick-annotated method invoked during binding or a custom view initializer.
Source
Thrown at butterknife/src/main/java/butterknife/ButterKnife.java:183
return Unbinder.EMPTY;
}
//noinspection TryWithIdenticalCatches Resolves to API 19+ only type.
try {
return constructor.newInstance(target, source);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unable to invoke " + constructor, e);
} catch (InstantiationException e) {
throw new RuntimeException("Unable to invoke " + constructor, e);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
}
if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException("Unable to create binding instance.", cause);
}
}
@Nullable @CheckResult @UiThread
private static Constructor<? extends Unbinder> findBindingConstructorForClass(Class<?> cls) {
Constructor<? extends Unbinder> bindingCtor = BINDINGS.get(cls);
if (bindingCtor != null || BINDINGS.containsKey(cls)) {
if (debug) Log.d(TAG, "HIT: Cached in binding map.");
return bindingCtor;
}
String clsName = cls.getName();
if (clsName.startsWith("android.") || clsName.startsWith("java.")
|| clsName.startsWith("androidx.")) {
if (debug) Log.d(TAG, "MISS: Reached framework class. Abandoning search.");
return null;
}
try {
Class<?> bindingClass = cls.getClassLoader().loadClass(clsName + "_ViewBinding");View on GitHub (pinned to fcdebedf32)
Solutions
- Read the cause of the RuntimeException (getCause()) in the stack trace — it names the actual class/line inside the constructor that failed; fix that root cause, not the ButterKnife wrapper.
- If a bound view or callback executes work during construction, move that work out of the binding path (e.g. post it to the view or run it after ButterKnife.bind returns).
- Verify the layout passed to setContentView matches the layout the @BindView IDs come from — wrong layouts usually surface as IllegalStateException missing-view errors that can chain into confusing wrapped causes.
- Clean build and align butterknife compiler/runtime versions to rule out malformed generated code before blaming user code.
Example fix
// before: the real failure is hidden inside the wrapper
// java.lang.RuntimeException: Unable to create binding instance.
// Caused by: java.io.IOException: ... thrown from custom view init
ButterKnife.bind(this);
// after: unwrap and handle the true cause at its source
try {
unbinder = ButterKnife.bind(this);
} catch (RuntimeException e) {
Throwable root = e;
while (root.getCause() != null) root = root.getCause();
Log.e(TAG, "Binding failed", root);
throw e;
} Defensive patterns
Strategy: try-catch
Try / catch
try {
unbinder = ButterKnife.bind(this);
} catch (RuntimeException e) {
// Unwrap: the true failure is the deepest cause, thrown from inside the generated ctor.
Throwable root = e;
while (root.getCause() != null) root = root.getCause();
Log.e(TAG, "Binding failed with root cause", root);
throw e; // surface the real problem in crash reports
} Prevention
- Never do IO, disk, or network work inside custom View constructors or @BindView field initializers.
- Trigger listeners only after ButterKnife.bind returns, never during binding setup.
- Ensure the layout in setContentView matches the layout the IDs come from to avoid chained missing-view failures.
- Always inspect getCause() chains in ButterKnife crashes instead of stopping at the wrapper message.
When it happens
Trigger: The generated Foo_ViewBinding constructor (or code it calls, e.g. a listener setup that immediately calls back into user code, or an unfolding/binding of a custom view whose constructor throws a checked exception wrapped by user code) throws a checked exception (e.g. IOException, NoSuchFieldException from reflection in user code) while ButterKnife.bind(...) runs. Look at the wrapped cause: it is the real failure thrown from inside the generated constructor.
Common situations: A custom View or a field initializer that performs IO/reflective work and throws a checked exception wrapped in a RuntimeException that itself has a checked cause; listeners fired synchronously during binding (e.g. programmatically triggering a click on a bound view before bind returns); classpath issues where a user class shadows the expected type and throws from an unexpected path.
Related errors
- Unable to find binding constructor for {}
- must not be private.
- More than one bind annotation on
- @BindView fields must extend from View or be an interface. (
- @BindViews List must have a generic component. (
AI-assisted analysis of JakeWharton/butterknife@fcdebedf32 (2026-08-14).
Data as JSON: /api/errors/23a2c214b81cd2a6.
Report an issue: GitHub.