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

Motion path theme attribute must either be an enum value or

Error message

Motion path theme attribute must either be an enum value or path data string

What it means

While resolving the motionPath theme attribute, TransitionUtils accepts exactly two TypedValue types: TYPE_INT_DEC (enum 0=linear, 1=arc) and TYPE_STRING (path data parsed by PathParser into a PatternPathMotion). If the attribute resolves to any other type — a float/dimension (TYPE_DIMENSION, TYPE_FLOAT), a color, a boolean, or a reference to a non-string resource — the else branch throws IllegalArgumentException('Motion path theme attribute must either be an enum value or path data string'). The message names the required contract.

Source

Thrown at lib/java/com/google/android/material/transition/platform/TransitionUtils.java:119

  @Nullable
  static PathMotion resolveThemePath(Context context, @AttrRes int attrResId) {
    TypedValue pathValue = new TypedValue();
    if (context.getTheme().resolveAttribute(attrResId, pathValue, true)) {
      if (pathValue.type == TypedValue.TYPE_INT_DEC) {
        int pathInt = pathValue.data;
        if (pathInt == PATH_TYPE_LINEAR) {
          // Default Transition PathMotion is linear; no need to override with different PathMotion.
          return null;
        } else if (pathInt == PATH_TYPE_ARC) {
          return new MaterialArcMotion();
        } else {
          throw new IllegalArgumentException("Invalid motion path type: " + pathInt);
        }
      } else if (pathValue.type == TypedValue.TYPE_STRING) {
        String pathString = String.valueOf(pathValue.string);
        return new PatternPathMotion(PathParser.createPathFromPathData(pathString));
      } else {
        throw new IllegalArgumentException(
            "Motion path theme attribute must either be an enum value or path data string");
      }
    }
    return null;
  }

  static ShapeAppearanceModel convertToRelativeCornerSizes(
      ShapeAppearanceModel shapeAppearanceModel, final RectF bounds) {
    return shapeAppearanceModel.withTransformedCornerSizes(
        cornerSize -> RelativeCornerSize.createFromCornerSize(bounds, cornerSize));
  }

  // TODO: rethink how to interpolate more than just corner size
  static ShapeAppearanceModel transformCornerSizes(
      ShapeAppearanceModel shapeAppearanceModel1,
      ShapeAppearanceModel shapeAppearanceModel2,
      RectF shapeAppearanceModel1Bounds,
      CornerSizeBinaryOperator op) {

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Change the theme item to a plain integer (0 or 1) or a path-data string literal, matching the attribute's declared format (enum|string).
  2. If the value lives in another resource, inline it as a string literal — references that resolve to non-int/non-string types are rejected.
  3. Run aapt2 dump or lint on the final merged resources to find which merged theme supplies the bad-typed value.
  4. If you control the attr declaration, keep its format="enum|string" so aapt rejects invalid types at build time.

Example fix

<!-- before -->
<item name="motionPath">@dimen/arc_amount</item>

<!-- after -->
<item name="motionPath">1</item> <!-- arc -->
Defensive patterns

Strategy: validation

Validate before calling

TypedValue v = new TypedValue();
if (context.getTheme().resolveAttribute(R.attr.motionPath, v, true)) {
  if (v.type != TypedValue.TYPE_INT_DEC && v.type != TypedValue.TYPE_STRING) {
    throw new IllegalStateException(
        "motionPath must be an enum int (0/1) or a path data string, was type " + v.type);
  }
}

Try / catch

try {
  applyThemePathMotion(context, transition, R.attr.motionPath);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().contains("must either be an enum value")) {
    transition.setPathMotion(new MaterialArcMotion()); // sensible default instead of crash
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Setting the motionPath theme item to a dimen (@dimen/motion_path), a boolean, a reference to another resource (<item name="motionPath">@string/curve</item> is a string so OK, but @integer/... via reference, or a raw float like 0.5), or a color value; tools generating theme values with the wrong aapt type.

Common situations: Design tokens pipelines writing a numeric token into the attribute; copy-paste between attrs with different formats (e.g., putting a dimen where an enum/path belongs); theme overlays from a library that declare the attr with an incompatible format.

Related errors


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