DrKLO/Telegram · error · UnsupportedOperationException

GridLayoutManager does not support stack from end. Consider

Error message

GridLayoutManager does not support stack from end. Consider using reverse layout

What it means

GridLayoutManager lays out items into a grid of spans. setStackFromEnd (a LinearLayoutManager feature that makes the list start from the bottom/end and pad to the top) has no coherent meaning for a grid because the span grouping logic assumes forward fill from a start anchor. The class explicitly forbids enabling it and points the developer to setReverseLayout, which achieves an end-anchored layout while keeping the grid math valid. Calling setStackFromEnd(true) is therefore a configuration error, not a runtime fault.

Source

Thrown at TMessagesProj/src/main/java/androidx/recyclerview/widget/GridLayoutManager.java:95

     * @param spanCount The number of columns or rows in the grid
     * @param orientation Layout orientation. Should be {@link #HORIZONTAL} or {@link
     *                      #VERTICAL}.
     * @param reverseLayout When set to true, layouts from end to start.
     */
    public GridLayoutManager(Context context, int spanCount,
            @RecyclerView.Orientation int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
        setSpanCount(spanCount);
    }

    /**
     * stackFromEnd is not supported by GridLayoutManager. Consider using
     * {@link #setReverseLayout(boolean)}.
     */
    @Override
    public void setStackFromEnd(boolean stackFromEnd) {
        if (stackFromEnd) {
            throw new UnsupportedOperationException(
                    "GridLayoutManager does not support stack from end."
                            + " Consider using reverse layout");
        }
        super.setStackFromEnd(false);
    }

    @Override
    public int getRowCountForAccessibility(RecyclerView.Recycler recycler,
            RecyclerView.State state) {
        if (mOrientation == HORIZONTAL) {
            return mSpanCount;
        }
        if (state.getItemCount() < 1) {
            return 0;
        }

        // Row count is one more than the last item's row index.
        return getSpanGroupIndex(recycler, state, state.getItemCount() - 1) + 1;

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Use setReverseLayout(true) on the GridLayoutManager to anchor content at the end.
  2. Before calling setStackFromEnd, check the LayoutManager type and only apply it to LinearLayoutManager.
  3. Remove app:stackFromEnd='true' from XML when using GridLayoutManager.

Example fix

// before
GridLayoutManager glm = new GridLayoutManager(this, 3);
glm.setStackFromEnd(true); // throws

// after
GridLayoutManager glm = new GridLayoutManager(this, 3);
glm.setReverseLayout(true); // end-anchored, grid-safe
Defensive patterns

Strategy: type-guard

Validate before calling

// Only setStackFromEnd on LinearLayoutManager, never GridLayoutManager
void maybeSetStackFromEnd(RecyclerView.LayoutManager lm, boolean stack) {
    if (lm instanceof GridLayoutManager) {
        if (stack) ((GridLayoutManager) lm).setReverseLayout(true);
    } else if (lm instanceof LinearLayoutManager) {
        ((LinearLayoutManager) lm).setStackFromEnd(stack);
    }
}

Type guard

boolean isStackFromEndSafe(RecyclerView.LayoutManager lm) {
    return !(lm instanceof GridLayoutManager);
}

Prevention

When it happens

Trigger: Code path that sets setStackFromEnd(true) on a LayoutManager that is later swapped to (or always was) a GridLayoutManager; inflating a layout with app:stackFromEnd='true' on a RecyclerView whose LayoutManager is a GridLayoutManager; sharing a config builder between LinearLayoutManager and GridLayoutManager.

Common situations: Porting a chat-style reverse list (which used LinearLayoutManager.setStackFromEnd) into a grid; XML attribute inherited from a template; setting stackFromEnd defensively without checking the LayoutManager type.

Related errors


AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14). Data as JSON: /api/errors/90ee51bfd2de4391. Report an issue: GitHub.