material-components/material-components-android · error · IllegalArgumentException
Motion easing control point value must be between 0 and 1; i
Error message
Motion easing control point value must be between 0 and 1; instead got: %s
What it means
When parsing control points from a legacy cubic-bezier easing string, getLegacyControlPoint requires each of the four floats to be within [0, 1]; a value outside that range throws IllegalArgumentException including the offending number. This matches PathInterpolator's own constraint on control points (x-axis especially), enforced earlier with a clearer message.
Source
Thrown at lib/java/com/google/android/material/motion/MotionUtils.java:177
return isLegacyEasingType(easingString, EASING_TYPE_CUBIC_BEZIER)
|| isLegacyEasingType(easingString, EASING_TYPE_PATH);
}
private static boolean isLegacyEasingType(String easingString, String easingType) {
return easingString.startsWith(easingType + EASING_TYPE_FORMAT_START)
&& easingString.endsWith(EASING_TYPE_FORMAT_END);
}
private static String getLegacyEasingContent(String easingString, String easingType) {
return easingString.substring(
easingType.length() + EASING_TYPE_FORMAT_START.length(),
easingString.length() - EASING_TYPE_FORMAT_END.length());
}
private static float getLegacyControlPoint(String[] controlPoints, int index) {
float controlPoint = Float.parseFloat(controlPoints[index]);
if (controlPoint < 0 || controlPoint > 1) {
throw new IllegalArgumentException(
"Motion easing control point value must be between 0 and 1; instead got: "
+ controlPoint);
}
return controlPoint;
}
}
View on GitHub (pinned to ac7e18efee)
Solutions
- Clamp all four control point values to the [0, 1] range
- For overshoot/elastic curves, use an @interpolator resource built from a PathInterpolator XML (paths may still be constrained, so prefer overshoot interpolators)
- Use built-in material easing defaults for standard motion
Example fix
<!-- before --> <item name="motionEasingEmphasized">cubic-bezier(0.2, 0, 0, 1.3)</item> <!-- after --> <item name="motionEasingEmphasized">cubic-bezier(0.2, 0, 0, 1)</item>
Defensive patterns
Strategy: validation
Validate before calling
fun clampControlPoints(points: FloatArray): FloatArray =
FloatArray(points.size) { i -> points[i].coerceIn(0f, 1f) } Try / catch
catch (e: IllegalArgumentException) { Log.w(TAG, "Control point out of range; clamping", e); useClampedCurve() } Prevention
- Keep all four bezier control points in [0, 1]
- For overshoot motion use an overshoot interpolator resource instead of out-of-range y values
- Validate easing constants in unit tests
When it happens
Trigger: A theme string like 'cubic-bezier(1.2, 0, 0.2, 1)' or a negative control point resolved through resolveThemeInterpolator; Float.parseFloat succeeds but the range check fails.
Common situations: Copying CSS curves with y-values outside [0,1] (legal in CSS for overshoot, illegal here); negative values intended as anticipation; locale issues where a decimal comma breaks parsing into a different number.
Related errors
- Motion easing theme attribute must have 4 control points if
- Invalid motion easing type: %s
- Rounded corners without gap are not supported in contiguous
- invalid shadow size
- Keylines being linearly interpolated must have the same item
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/d3de4937ac25ce6d.
Report an issue: GitHub.