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

Invalid fade mode: > fadeMode <

Error message

Invalid fade mode: > fadeMode <

What it means

FadeModeEvaluators.get (FadeModeEvaluators.java:87) resolves how start/end views fade during a MaterialContainerTransform. Only the four @FadeMode constants (FADE_MODE_IN, FADE_MODE_OUT, FADE_MODE_CROSS, FADE_MODE_THROUGH) are valid; any other int hits the default branch and throws IllegalArgumentException. The value flows in from MaterialContainerTransform.setFadeMode().

Source

Thrown at lib/java/com/google/android/material/transition/FadeModeEvaluators.java:87

              fadeStartFraction + fadeFractionDiff * threshold;
          int startAlpha = lerp(255, 0, fadeStartFraction, fadeFractionThreshold, progress);
          int endAlpha = lerp(0, 255, fadeFractionThreshold, fadeEndFraction, progress);
          return FadeModeResult.startOnTop(startAlpha, endAlpha);
        }
      };

  static FadeModeEvaluator get(@FadeMode int fadeMode, boolean entering) {
    switch (fadeMode) {
      case FADE_MODE_IN:
        return entering ? IN : OUT;
      case FADE_MODE_OUT:
        return entering ? OUT : IN;
      case FADE_MODE_CROSS:
        return CROSS;
      case FADE_MODE_THROUGH:
        return THROUGH;
      default:
        throw new IllegalArgumentException("Invalid fade mode: " + fadeMode);
    }
  }

  private FadeModeEvaluators() {}
}

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Use the declared constants: MaterialContainerTransform.FADE_MODE_IN / FADE_MODE_OUT / FADE_MODE_CROSS / FADE_MODE_THROUGH.
  2. Validate externally sourced values against the 0..3 range before calling setFadeMode().
  3. Lint against raw ints: annotate your own wrapper parameter with @FadeMode so Android Studio enforces the constant set.

Example fix

// before
transform.setFadeMode(7);

// after
transform.setFadeMode(MaterialContainerTransform.FADE_MODE_THROUGH);
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidFadeMode(int m) {
  return m >= MaterialContainerTransform.FADE_MODE_IN
      && m <= MaterialContainerTransform.FADE_MODE_THROUGH;
}
if (isValidFadeMode(raw)) transform.setFadeMode(raw); else transform.setFadeMode(MaterialContainerTransform.FADE_MODE_IN);

Type guard

static @FadeMode int coerceFadeMode(int candidate) {
  switch (candidate) {
    case MaterialContainerTransform.FADE_MODE_IN:
    case MaterialContainerTransform.FADE_MODE_OUT:
    case MaterialContainerTransform.FADE_MODE_CROSS:
    case MaterialContainerTransform.FADE_MODE_THROUGH:
      return candidate;
    default: return MaterialContainerTransform.FADE_MODE_IN;
  }
}

Prevention

When it happens

Trigger: Calling transform.setFadeMode(n) with a raw int that is not one of MaterialContainerTransform.FADE_MODE_*; passing a persisted or bundled fadeMode that was corrupted; version drift where a custom constant was hardcoded numerically.

Common situations: Hardcoding 3 thinking it means THROUGH when valid values are 0-3 defined by annotation; copying an int from an older snippet; storing fadeMode in preferences/remote config without validation.

Related errors


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