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

Invalid fit mode: > fitMode <

Error message

Invalid fit mode: > fitMode <

What it means

Platform-package counterpart of the fit-mode evaluator (transition/platform/FitModeEvaluators.java:137) used by com.google.android.material.transition.platform.MaterialContainerTransform. It accepts only FIT_MODE_AUTO/WIDTH/HEIGHT; FIT_MODE_AUTO internally chooses WIDTH or HEIGHT by comparing fitted aspect ratios. Any other fitMode int reaches the default branch and throws IllegalArgumentException.

Source

Thrown at lib/java/com/google/android/material/transition/platform/FitModeEvaluators.java:137

        public void applyMask(RectF maskBounds, float maskMultiplier, FitModeResult fitModeResult) {
          float currentWidthDiff =
              Math.abs(fitModeResult.currentEndWidth - fitModeResult.currentStartWidth);
          maskBounds.left += currentWidthDiff / 2 * maskMultiplier;
          maskBounds.right -= currentWidthDiff / 2 * maskMultiplier;
        }
      };

  static FitModeEvaluator get(
      @FitMode int fitMode, boolean entering, RectF startBounds, RectF endBounds) {
    switch (fitMode) {
      case FIT_MODE_AUTO:
        return shouldAutoFitToWidth(entering, startBounds, endBounds) ? WIDTH : HEIGHT;
      case FIT_MODE_WIDTH:
        return WIDTH;
      case FIT_MODE_HEIGHT:
        return HEIGHT;
      default:
        throw new IllegalArgumentException("Invalid fit mode: " + fitMode);
    }
  }

  private static boolean shouldAutoFitToWidth(
      boolean entering, RectF startBounds, RectF endBounds) {
    float startWidth = startBounds.width();
    float startHeight = startBounds.height();
    float endWidth = endBounds.width();
    float endHeight = endBounds.height();

    float endHeightFitToWidth = endHeight * startWidth / endWidth;
    float startHeightFitToWidth = startHeight * endWidth / startWidth;
    return entering ? endHeightFitToWidth >= startHeight : startHeightFitToWidth >= endHeight;
  }

  private FitModeEvaluators() {}
}

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Pass only MaterialContainerTransform.FIT_MODE_AUTO / FIT_MODE_WIDTH / FIT_MODE_HEIGHT (platform variant).
  2. Whitelist-check external values before calling setFitMode().
  3. Annotate wrapper params with @FitMode for compile-time checks.

Example fix

// before
transform.setFitMode(2 + 2);

// after
transform.setFitMode(MaterialContainerTransform.FIT_MODE_HEIGHT);
Defensive patterns

Strategy: validation

Validate before calling

import com.google.android.material.transition.platform.MaterialContainerTransform;

static boolean isValidPlatformFitMode(int m) {
  return m == MaterialContainerTransform.FIT_MODE_AUTO
      || m == MaterialContainerTransform.FIT_MODE_WIDTH
      || m == MaterialContainerTransform.FIT_MODE_HEIGHT;
}
if (isValidPlatformFitMode(cfg)) transform.setFitMode(cfg); else transform.setFitMode(MaterialContainerTransform.FIT_MODE_AUTO);

Type guard

static int coercePlatformFitMode(int candidate) {
  return isValidPlatformFitMode(candidate) ? candidate : MaterialContainerTransform.FIT_MODE_AUTO;
}

Prevention

When it happens

Trigger: Calling setFitMode() on the platform MaterialContainerTransform with a raw or out-of-range int; reusing a fade-mode or axis constant in place of a fit-mode constant; deserialized fitMode values passed unchecked.

Common situations: Numeric hardcoding; constants confused across the two transition packages (platform vs androidx); config-driven transition styling with unvalidated ints.

Related errors


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