material-components/material-components-android · error · IllegalArgumentException
Invalid axis: > axis <
Error message
Invalid axis: > axis <
What it means
MaterialSharedAxis.createPrimaryAnimatorProvider (MaterialSharedAxis.java:116) maps the axis constant to the primary motion: X slides horizontally, Y slides vertically, Z scales. The @Axis annotation allows only X (0), Y (1), Z (2); any other int reaches the default branch and throws IllegalArgumentException when the shared-axis transition is created.
Source
Thrown at lib/java/com/google/android/material/transition/MaterialSharedAxis.java:116
public int getAxis() {
return axis;
}
public boolean isForward() {
return forward;
}
private static VisibilityAnimatorProvider createPrimaryAnimatorProvider(
@Axis int axis, boolean forward) {
switch (axis) {
case X:
return new SlideDistanceProvider(forward ? Gravity.END : Gravity.START);
case Y:
return new SlideDistanceProvider(forward ? Gravity.BOTTOM : Gravity.TOP);
case Z:
return new ScaleProvider(forward);
default:
throw new IllegalArgumentException("Invalid axis: " + axis);
}
}
private static VisibilityAnimatorProvider createSecondaryAnimatorProvider() {
return new FadeThroughProvider();
}
@AttrRes
@Override
int getDurationThemeAttrResId(boolean appearing) {
return DEFAULT_THEMED_DURATION_ATTR;
}
@AttrRes
@Override
int getEasingThemeAttrResId(boolean appearing) {
return DEFAULT_THEMED_EASING_ATTR;
}View on GitHub (pinned to ac7e18efee)
Solutions
- Use MaterialSharedAxis.X, MaterialSharedAxis.Y, or MaterialSharedAxis.Z when constructing the transition.
- Validate dynamic axis values: clamp or reject anything outside 0..2.
- Annotate your own config-layer parameter with @Axis for lint-time enforcement.
Example fix
// before MaterialSharedAxis axis = new MaterialSharedAxis(4, true); // invalid // after MaterialSharedAxis axis = new MaterialSharedAxis(MaterialSharedAxis.Z, true);
Defensive patterns
Strategy: validation
Validate before calling
static boolean isValidSharedAxis(int axis) {
return axis == MaterialSharedAxis.X || axis == MaterialSharedAxis.Y || axis == MaterialSharedAxis.Z;
}
if (!isValidSharedAxis(cfgAxis)) throw new IllegalArgumentException("axis must be X, Y or Z");
new MaterialSharedAxis(cfgAxis, true); Type guard
static @Axis int coerceAxis(int a) {
return isValidSharedAxis(a) ? a : MaterialSharedAxis.Y;
} Prevention
- Construct MaterialSharedAxis only with its X/Y/Z constants.
- Keep transition config ints typed (dedicated fields per knob) to prevent constant mix-ups.
- Validate deserialized config in one choke point before creating transitions.
When it happens
Trigger: Calling MaterialSharedAxis(MaterialSharedAxis.XYZ_SOMETHING, true) with an invalid int — typically a hardcoded number or a constant imported from the wrong class; constructing MaterialSharedAxis(axis, true) where axis came from serialization/bundles unchecked.
Common situations: Numeric literals instead of MaterialSharedAxis.X/Y/Z; constants mixed up with gravity or fade-mode values; code-generation or JSON-driven transition config that feeds raw ints.
Related errors
- Invalid motion path type: > pathInt <
- Invalid axis: > axis <
- no button data for mode: > mode <
- Invalid fade mode: > fadeMode <
- Invalid fit mode: > fitMode <
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/b33d7113eaf239a7.
Report an issue: GitHub.