airbnb/epoxy · error · IllegalStateException

numItemsToPrefetch must be greater than 0

Error message

numItemsToPrefetch must be greater than 0

What it means

Carousel.setInitialPrefetchItemCount configures LinearLayoutManager.setInitialPrefetchItemCount for nested-scrolling prefetching, which requires a positive count. Passing a negative value throws; note 0 is tolerated and treated as the default of 2.

Solutions

  1. Pass a value >= 0; use 0 to get the default prefetch count of 2.
  2. Clamp the computed value: Math.max(0, computedCount).
  3. If you intend to disable prefetch, the API does not support negative counts — use 0 (default) instead.

Example fix

// before
carousel.setInitialPrefetchItemCount(-1); // throws

// after
carousel.setInitialPrefetchItemCount(Math.max(0, computedCount));
Defensive patterns

Strategy: validation

Validate before calling

if (prefetchCount < 0) prefetchCount = 0; // 0 means default of 2
carousel.setInitialPrefetchItemCount(prefetchCount);

Prevention

When it happens

Trigger: Calling carousel.setInitialPrefetchItemCount(n) with n < 0, e.g. via @ModelProp(group="prefetch") binding in a controller with a negative computed value.

Common situations: Computing prefetch count from a variable that can go negative (e.g. itemsToPrefetch - shownItems), or misunderstanding that 0 means 'use default 2' and passing -1 intending 'disable prefetch'.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of airbnb/epoxy@e45bd3a61f (2026-09-13). Data as JSON: /api/errors/263eeaea385be22c. Report an issue: GitHub.

Appendix: source

Thrown at epoxy-adapter/src/main/java/com/airbnb/epoxy/Carousel.java:179

  /**
   * @return The number of views to show on screen in this carousel at a time.
   */
  public float getNumViewsToShowOnScreen() {
      return numViewsToShowOnScreen;
  }

  /**
   * If you are using a Linear or Grid layout manager you can use this to set the item prefetch
   * count. Only use this if you are not using {@link #setNumViewsToShowOnScreen(float)}
   *
   * @see #setNumViewsToShowOnScreen(float)
   * @see LinearLayoutManager#setInitialPrefetchItemCount(int)
   */
  @ModelProp(group = "prefetch")
  public void setInitialPrefetchItemCount(int numItemsToPrefetch) {
    if (numItemsToPrefetch < 0) {
      throw new IllegalStateException("numItemsToPrefetch must be greater than 0");
    }

    // Use the linearlayoutmanager default of 2 if the user did not specify one
    int prefetchCount = numItemsToPrefetch == 0 ? 2 : numItemsToPrefetch;

    LayoutManager layoutManager = getLayoutManager();
    if (layoutManager instanceof LinearLayoutManager) {
      ((LinearLayoutManager) layoutManager).setInitialPrefetchItemCount(prefetchCount);
    }
  }

  @Override
  public void onChildAttachedToWindow(View child) {
    if (numViewsToShowOnScreen > 0) {
      ViewGroup.LayoutParams childLayoutParams = child.getLayoutParams();
      child.setTag(R.id.epoxy_recycler_view_child_initial_size_id, childLayoutParams.width);

      int itemSpacingPx = getSpacingDecorator().getPxBetweenItems();

View on GitHub (pinned to e45bd3a61f)