material-components/material-components-android · error · IllegalArgumentException

Custom size must be non-negative

Error message

Custom size must be non-negative

What it means

FloatingActionButton.setCustomSize(@Px int size) sets an explicit pixel size for the FAB. Only zero (FloatingActionButton.NO_CUSTOM_SIZE, meaning 'no custom size') or positive values are legal; a negative size cannot produce a valid measurement so the method throws IllegalArgumentException.

Source

Thrown at lib/java/com/google/android/material/floatingactionbutton/FloatingActionButton.java:809

  }

  public boolean isOrWillBeShown() {
    return getImpl().isOrWillBeShown();
  }

  /**
   * Sets the size of the button to be a custom value in pixels.
   *
   * <p>If you've set a custom size and would like to clear it, you can use the {@link
   * #clearCustomSize()} method. If called, custom sizing will not be used and the size will be
   * calculated based on the value set using {@link #setSize(int)} or the {@code fabSize} attribute.
   *
   * @param size preferred size in pixels, or {@link #NO_CUSTOM_SIZE}
   * @attr ref com.google.android.material.R.styleable#FloatingActionButton_fabCustomSize
   */
  public void setCustomSize(@Px int size) {
    if (size < 0) {
      throw new IllegalArgumentException("Custom size must be non-negative");
    }

    if (size != customSize) {
      customSize = size;
      requestLayout();
    }
  }

  /**
   * Returns the custom size for this {@link FloatingActionButton}.
   *
   * @return size in pixels, or {@link #NO_CUSTOM_SIZE}
   */
  @Px
  public int getCustomSize() {
    return customSize;
  }

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Normalize before calling: if (size > 0) fab.setCustomSize(size) else fab.clearCustomSize();
  2. Never use negative sentinels; use FloatingActionButton.NO_CUSTOM_SIZE (0) or a nullable Integer checked for null.
  3. Clamp computed sizes: Math.max(0, computedSizePx) and confirm dimension math cannot underflow on the smallest supported screens.

Example fix

// before
int size = prefs.getInt("fab_size", -1);
fab.setCustomSize(size); // -1 -> IllegalArgumentException

// after
int size = prefs.getInt("fab_size", FloatingActionButton.NO_CUSTOM_SIZE);
if (size > 0) {
  fab.setCustomSize(size);
} else {
  fab.clearCustomSize();
}
Defensive patterns

Strategy: validation

Validate before calling

if (size > 0) {
  fab.setCustomSize(size);
} else {
  fab.clearCustomSize();
}

Prevention

When it happens

Trigger: Passing a negative pixel value, e.g. setCustomSize(-1) used as a sentinel by app code; computing size from a dimension difference that can go negative (padding larger than requested size); unboxing an Integer/nullable boxed value that defaults to -1 when absent from config.

Common situations: Using -1 as 'not set' sentinel then forwarding it directly to setCustomSize; resizing FABs responsively (screen width minus margins) on small screens or multi-window where the calculation underflows; data-driven UI where size comes from a backend/JSON field.

Related errors


AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14). Data as JSON: /api/errors/d7f3509f59083720. Report an issue: GitHub.