material-components/material-components-android · error · IllegalArgumentException
Motion easing theme attribute must have 4 control points if
Error message
Motion easing theme attribute must have 4 control points if using bezier curve format; instead got: %d
What it means
For legacy string easings in the cubic-bezier format, MotionUtils splits the content on commas and requires exactly 4 control points. 'cubic-bezier(0.2,0,0,1)' yields 4 tokens; anything else (too few, too many, or empty segments) throws IllegalArgumentException with the count received.
Source
Thrown at lib/java/com/google/android/material/motion/MotionUtils.java:139
"Motion easing theme attribute must be an @interpolator resource for"
+ " ?attr/motionEasing*Interpolator attributes or a string for"
+ " ?attr/motionEasing* attributes.");
}
String easingString = String.valueOf(easingValue.string);
if (isLegacyEasingAttribute(easingString)) {
return getLegacyThemeInterpolator(easingString);
}
return AnimationUtils.loadInterpolator(context, easingValue.resourceId);
}
private static TimeInterpolator getLegacyThemeInterpolator(String easingString) {
if (isLegacyEasingType(easingString, EASING_TYPE_CUBIC_BEZIER)) {
String controlPointsString = getLegacyEasingContent(easingString, EASING_TYPE_CUBIC_BEZIER);
String[] controlPoints = controlPointsString.split(",");
if (controlPoints.length != 4) {
throw new IllegalArgumentException(
"Motion easing theme attribute must have 4 control points if using bezier curve"
+ " format; instead got: "
+ controlPoints.length);
}
float controlX1 = getLegacyControlPoint(controlPoints, 0);
float controlY1 = getLegacyControlPoint(controlPoints, 1);
float controlX2 = getLegacyControlPoint(controlPoints, 2);
float controlY2 = getLegacyControlPoint(controlPoints, 3);
return new PathInterpolator(controlX1, controlY1, controlX2, controlY2);
} else if (isLegacyEasingType(easingString, EASING_TYPE_PATH)) {
String path = getLegacyEasingContent(easingString, EASING_TYPE_PATH);
return new PathInterpolator(PathParser.createPathFromPathData(path));
} else {
throw new IllegalArgumentException("Invalid motion easing type: " + easingString);
}
}
View on GitHub (pinned to ac7e18efee)
Solutions
- Write exactly four comma-separated numbers inside cubic-bezier(...)
- Prefer the @interpolator resource form (PathInterpolator XML) which is parsed by the framework and less error-prone
- Unit-test custom easing strings with a split(",").length == 4 assertion
Example fix
<!-- before --> <item name="motionEasingStandard">cubic-bezier(0.4, 0)</item> <!-- after --> <item name="motionEasingStandard">cubic-bezier(0.4, 0, 0.2, 1)</item>
Defensive patterns
Strategy: validation
Validate before calling
// Validate a cubic-bezier easing string before applying it
fun isValidBezierEasing(s: String): Boolean {
if (!s.startsWith("cubic-bezier(") || !s.endsWith(")")) return false
val parts = s.removePrefix("cubic-bezier(").removeSuffix(")").split(",")
if (parts.size != 4) return false
return parts.all { it.trim().toFloatOrNull() != null }
} Try / catch
catch (e: IllegalArgumentException) { Log.w(TAG, "Malformed easing string; using default", e); useDefaultEasing() } Prevention
- Copy easing strings from verified material theme sources
- Prefer @interpolator XML resources over hand-typed strings
- Unit-test custom easing strings for format and point count
When it happens
Trigger: A theme attribute value like 'cubic-bezier(0.4)' or 'cubic-bezier(0.2, 0, 0, 1, 0.5)' passed to resolveThemeInterpolator; also 'cubic-bezier(,)' style typos where empty strings still count as tokens.
Common situations: Hand-authoring easing strings in themes; translating CSS cubic-bezier values and dropping a component; trailing commas; whitespace variants that alter split counts only when segments are missing.
Related errors
- Motion easing control point value must be between 0 and 1; i
- Invalid motion easing type: %s
- Keylines being linearly interpolated must have the same item
- Keylines being linearly interpolated must have the same numb
- Caller must set a non-null RevealInfo before calling this.
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/3c1470d4a849288f.
Report an issue: GitHub.