JakeWharton/butterknife · error · IllegalStateException
Required view '{}' with ID {} for {} was not found. If this
Error message
Required view '{}' with ID {} for {} was not found. If this view is optional add '@Nullable' (fields) or '@Optional' (methods) annotation. What it means
Thrown by Utils.findRequiredView (used by generated/reflect bindings for non-@Nullable @BindView fields and non-@Optional listener methods) when findViewById for the requested ID returns null on the bound source view hierarchy. The message includes the resource entry name, numeric ID, and the 'who' description (class.field), and tells you the escape hatches.
Source
Thrown at butterknife-runtime/src/main/java/butterknife/internal/Utils.java:84
@SafeVarargs
public static <T> List<T> listFilteringNull(T... views) {
return new ImmutableList<>(arrayFilteringNull(views));
}
public static <T> T findOptionalViewAsType(View source, @IdRes int id, String who,
Class<T> cls) {
View view = source.findViewById(id);
return castView(view, id, who, cls);
}
public static View findRequiredView(View source, @IdRes int id, String who) {
View view = source.findViewById(id);
if (view != null) {
return view;
}
String name = getResourceEntryName(source, id);
throw new IllegalStateException("Required view '"
+ name
+ "' with ID "
+ 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);View on GitHub (pinned to fcdebedf32)
Solutions
- Verify the inflated layout actually declares the ID; align flavor/orientation variants that omit it.
- Move ButterKnife.bind into onCreateView/onViewCreated (fragment) or after setContentView (activity).
- If the view is genuinely optional, annotate the field @Nullable (butterknife.@Nullable) or the method @Optional so a missing view is skipped.
Example fix
// before @BindView(R.id.subtitle) TextView subtitle; // absent in landscape layout // after @Nullable @BindView(R.id.subtitle) TextView subtitle; // null-safe in landscape
Defensive patterns
Strategy: validation
Validate before calling
// Before bind: confirm the required view exists
View v = sourceView.findViewById(R.id.subtitle);
if (v == null && !fieldIsAnnotatedNullable) {
// align layout, bind later, or mark @Nullable
} Prevention
- Bind after the view hierarchy exists (post-setContentView / onViewCreated).
- Keep layout variants (landscape, flavors) in sync for every bound ID.
- Mark genuinely optional fields @Nullable and methods @Optional instead of catching the exception.
When it happens
Trigger: ButterKnife.bind(this) where @BindView(R.id.title) is required, but the content view inflated (setContentView / fragment layout) has no view with that ID — wrong layout inflated, ID only in a different flavor/build variant layout, child view not yet inflated, or binding on the wrong source (ButterKnife.bind(this, drawerHeader) etc.).
Common situations: Landscape/night/flavor layout variants missing a view present in the default layout; multi-pane vs single-pane layout swap; binding before the view exists (bind before setContentView, or in a fragment before onViewCreated); binding a header/footer row layout where the ID belongs to the row layout but bind was called on the item container. Library consumers commonly hit it after renaming or removing an ID in XML while annotations still reference it.
Related errors
- View '{}' with ID {} for {} was of the wrong type. See cause
- @%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.
AI-assisted analysis of JakeWharton/butterknife@fcdebedf32 (2026-08-14).
Data as JSON: /api/errors/667962736d39c40e.
Report an issue: GitHub.