DrKLO/Telegram · error · IllegalArgumentException

Span count should be at least 1. Provided {}

Error message

Span count should be at least 1. Provided {}

What it means

GridLayoutManager organizes items into exactly spanCount spans (rows or columns). A span count of 0 or negative makes the grid undefined (no lanes to place items into, division by zero in span math), so setSpanCount enforces a minimum of 1. The check runs on construction and on runtime changes; mSpanCount is used pervasively in division/loop bounds, so an invalid value would corrupt layout immediately. The most common trigger is a computed span count (from screen width or orientation) that evaluated to 0 because of an unfetched resource or a not-yet-laid-out view.

Source

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

        return mSpanCount;
    }

    /**
     * Sets the number of spans to be laid out.
     * <p>
     * If {@link #getOrientation()} is {@link #VERTICAL}, this is the number of columns.
     * If {@link #getOrientation()} is {@link #HORIZONTAL}, this is the number of rows.
     *
     * @param spanCount The total number of spans in the grid
     * @see #getSpanCount()
     */
    public void setSpanCount(int spanCount) {
        if (spanCount == mSpanCount) {
            return;
        }
        mPendingSpanCountChange = true;
        if (spanCount < 1) {
            throw new IllegalArgumentException("Span count should be at least 1. Provided "
                    + spanCount);
        }
        mSpanCount = spanCount;
        mSpanSizeLookup.invalidateSpanIndexCache();
        requestLayout();
    }

    /**
     * A helper class to provide the number of spans each item occupies.
     * <p>
     * Default implementation sets each item to occupy exactly 1 span.
     *
     * @see GridLayoutManager#setSpanSizeLookup(SpanSizeLookup)
     */
    public abstract static class SpanSizeLookup {

        final SparseIntArray mSpanIndexCache = new SparseIntArray();
        final SparseIntArray mSpanGroupIndexCache = new SparseIntArray();

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Clamp the computed span count: setSpanCount(Math.max(1, computed)).
  2. Defer setSpanCount until after View.Layout/ViewTreeObserver reports real dimensions.
  3. Validate any external/user-provided span count against >= 1 before applying.

Example fix

// before
int columns = displayMetrics.widthPixels / itemWidthPx; // 0 if metrics stale
new GridLayoutManager(this, columns); // throws

// after
int columns = Math.max(1, displayMetrics.widthPixels / itemWidthPx);
new GridLayoutManager(this, columns);
Defensive patterns

Strategy: validation

Validate before calling

// Clamp span count to at least 1
int safeSpanCount(int displayWidth, int itemWidthPx) {
    return Math.max(1, displayWidth / Math.max(1, itemWidthPx));
}
new GridLayoutManager(this, safeSpanCount(widthPx, itemPx));

Prevention

When it happens

Trigger: Computing spanCount as displayMetrics.widthPixels / itemWidthPx before display metrics are available (returns 0); passing a value from preferences/JSON that is 0; a calculation like (count - N) that goes to 0 or negative for small counts; calling setSpanCount during construction with a resource-derived value that defaulted to 0.

Common situations: Responsive grid that calculates columns from screen width but runs before onGlobalLayout; orientation change recomputing span count before the new metrics load; a settings screen where the user could set columns to 0; dividing by a dp-to-px factor that resolved to 0.

Related errors


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