DrKLO/Telegram · error · IllegalArgumentException
Invalid direction: {direction}
Error message
Invalid direction: {direction} What it means
RecyclerView's internal focus-search helper resolves whether a candidate is 'closer' in a given focus direction. Its switch covers FOCUS_LEFT/RIGHT/UP/DOWN/FORWARD/BACKWARD; any other direction constant throws 'Invalid direction'. The focus machinery cannot rank candidates for an axis-less direction.
Source
Thrown at TMessagesProj/src/main/java/androidx/recyclerview/widget/RecyclerView.java:2895
|| mTempRect.top >= mTempRect2.bottom)
&& mTempRect.top > mTempRect2.top) {
downness = -1;
}
switch (direction) {
case View.FOCUS_LEFT:
return rightness < 0;
case View.FOCUS_RIGHT:
return rightness > 0;
case View.FOCUS_UP:
return downness < 0;
case View.FOCUS_DOWN:
return downness > 0;
case View.FOCUS_FORWARD:
return downness > 0 || (downness == 0 && rightness * rtl > 0);
case View.FOCUS_BACKWARD:
return downness < 0 || (downness == 0 && rightness * rtl < 0);
}
throw new IllegalArgumentException("Invalid direction: " + direction + exceptionLabel());
}
@Override
public void requestChildFocus(View child, View focused) {
if (!mLayout.onRequestChildFocus(this, mState, child, focused) && focused != null) {
requestChildOnScreen(child, focused);
}
super.requestChildFocus(child, focused);
}
/**
* Requests that the given child of the RecyclerView be positioned onto the screen. This method
* can be called for both unfocusable and focusable child views. For unfocusable child views,
* the {@param focused} parameter passed is null, whereas for a focusable child, this parameter
* indicates the actual descendant view within this child view that holds the focus.
* @param child The child view of this RecyclerView that wants to come onto the screen.
* @param focused The descendant view that actually has the focus if child is focusable, null
* otherwise.View on GitHub (pinned to 45ab8f4308)
Solutions
- Use only View.FOCUS_LEFT, FOCUS_RIGHT, FOCUS_UP, FOCUS_DOWN, FOCUS_FORWARD, FOCUS_BACKWARD.
- Validate the direction against the set of known constants before invoking focus search.
- If you only need nearest-neighbor focus, rely on the default arrow-key handling instead of custom direction injection.
Example fix
// before recyclerView.focusSearch(focusedView, myCustomDir); // e.g. 0 // after int dir = View.FOCUS_FORWARD; // one of the six valid constants recyclerView.focusSearch(focusedView, dir);
Defensive patterns
Strategy: validation
Validate before calling
static boolean isValidFocusDirection(int dir) {
return dir == View.FOCUS_LEFT || dir == View.FOCUS_RIGHT
|| dir == View.FOCUS_UP || dir == View.FOCUS_DOWN
|| dir == View.FOCUS_FORWARD || dir == View.FOCUS_BACKWARD;
}
if (isValidFocusDirection(dir)) {
recyclerView.focusSearch(view, dir);
} Type guard
static boolean isKnownFocusDirection(int dir) {
switch (dir) {
case View.FOCUS_LEFT: case View.FOCUS_RIGHT:
case View.FOCUS_UP: case View.FOCUS_DOWN:
case View.FOCUS_FORWARD: case View.FOCUS_BACKWARD:
return true;
default: return false;
}
} Try / catch
null
Prevention
- Use only the six View.FOCUS_* constants.
- Do not pass 0 or custom constants into focusSearch.
- Rely on default arrow-key handling instead of injecting custom directions.
When it happens
Trigger: An external caller (accessibility service, custom keyboard handler, test framework) invoking focusSearch with a direction constant outside the six known View.FOCUS_* values (e.g. View.FOCUS_DOWN === 130 but a typo or a custom constant like 0).
Common situations: Passing 0 or an arbitrary int as direction in requestFocus/arrowScroll tests. Custom focus handling that invents a direction constant.
Related errors
- Must pass a ViewHolder when dragging
- invalid orientation:{}
- snap preference should be one of the constants defined in Sm
- invalid orientation
- {positionDescription}: Cannot access non-public constructor
AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14).
Data as JSON: /api/errors/c02084c148ef8a1e.
Report an issue: GitHub.