{"record":{"id":"1ad9a2a981f07af2","repo":"material-components/material-components-android","slug":"animator-must-be-an-objectanimator","errorCode":null,"errorMessage":"Animator must be an ObjectAnimator: ","messagePattern":"Animator must be an ObjectAnimator: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/animation/MotionSpec.java","lineNumber":220,"sourceCode":"    }\n  }\n\n  @NonNull\n  private static MotionSpec createSpecFromAnimators(@NonNull List<Animator> animators) {\n    MotionSpec spec = new MotionSpec();\n    for (int i = 0, count = animators.size(); i < count; i++) {\n      addInfoFromAnimator(spec, animators.get(i));\n    }\n    return spec;\n  }\n\n  private static void addInfoFromAnimator(@NonNull MotionSpec spec, Animator animator) {\n    if (animator instanceof ObjectAnimator) {\n      ObjectAnimator anim = (ObjectAnimator) animator;\n      spec.setPropertyValues(anim.getPropertyName(), anim.getValues());\n      spec.setTiming(anim.getPropertyName(), MotionTiming.createFromAnimator(anim));\n    } else {\n      throw new IllegalArgumentException(\"Animator must be an ObjectAnimator: \" + animator);\n    }\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (!(o instanceof MotionSpec)) {\n      return false;\n    }\n\n    MotionSpec that = (MotionSpec) o;\n\n    return timings.equals(that.timings);\n  }\n\n  @Override","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/animation/MotionSpec.java#L202-L238","documentation":"MotionSpec.createFromAnimatorSpec(AnimatorSet) (and related inflate paths) extracts per-property timing information from each child Animator via addInfoFromAnimator. Only ObjectAnimator carries a property name and PropertyValuesHolder data that MotionSpec can record, so any other Animator subtype (e.g. plain ValueAnimator or AnimatorSet) is rejected with IllegalArgumentException.","triggerScenarios":"Calling MotionSpec.createFromAnimatorSpec with an AnimatorSet containing a ValueAnimator, TimeAnimator, or nested AnimatorSet instead of ObjectAnimator children; building an AnimatorSet in code where one child was created with ValueAnimator.ofInt/ofFloat.","commonSituations":"Hand-building an AnimatorSet to drive a Material component motion (e.g. MaterialCarousel or dismissible item animations) and mixing in a ValueAnimator for a non-property animation; converting an XML animator resource whose child is a <animator> (ValueAnimator) rather than <objectAnimator>.","solutions":["Replace every non-ObjectAnimator child with an ObjectAnimator (use ObjectAnimator.ofFloat/ofInt with a target and property name, or PropertyValuesHolder).","If animating a raw value with no target property, wrap the logic in a custom Property implementation and use ObjectAnimator with it.","Check XML animator resources use <objectAnimator> elements, not <animator>."],"exampleFix":"// before\nAnimatorSet set = new AnimatorSet();\nset.playTogether(ValueAnimator.ofFloat(0f, 1f)); // throws\nMotionSpec spec = MotionSpec.createFromAnimatorSpec(set);\n\n// after\nObjectAnimator fade = ObjectAnimator.ofFloat(view, View.ALPHA, 0f, 1f);\nAnimatorSet set = new AnimatorSet();\nset.playTogether(fade);\nMotionSpec spec = MotionSpec.createFromAnimatorSpec(set);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"private static boolean allChildrenAreObjectAnimators(AnimatorSet set) {\n  for (Animator child : set.getChildAnimations()) {\n    if (!(child instanceof ObjectAnimator)) return false;\n  }\n  return true;\n}","tryCatchPattern":null,"preventionTips":["Build animator sets exclusively from ObjectAnimator when they feed MotionSpec.","Prefer MotionSpec.createFromResource(context, animResId) with verified <objectAnimator> XML."],"tags":["animation","motionspec","illegal-argument","objectanimator"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}