{"record":{"id":"082ca8443eac929a","repo":"material-components/material-components-android","slug":"invalid-transition-direction-transitiondirectio","errorCode":null,"errorMessage":"Invalid transition direction: > transitionDirection <","messagePattern":"Invalid transition direction: > transitionDirection <","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/transition/MaterialContainerTransform.java","lineNumber":1041,"sourceCode":"    if (boundingView != null) {\n      RectF drawableBounds = getLocationInWindow(boundingView);\n      drawableBounds.offset(offsetX, offsetY);\n      return drawableBounds;\n    } else {\n      return new RectF(0, 0, drawingView.getWidth(), drawingView.getHeight());\n    }\n  }\n\n  private boolean isEntering(@NonNull RectF startBounds, @NonNull RectF endBounds) {\n    switch (transitionDirection) {\n      case TRANSITION_DIRECTION_AUTO:\n        return calculateArea(endBounds) > calculateArea(startBounds);\n      case TRANSITION_DIRECTION_ENTER:\n        return true;\n      case TRANSITION_DIRECTION_RETURN:\n        return false;\n      default:\n        throw new IllegalArgumentException(\"Invalid transition direction: \" + transitionDirection);\n    }\n  }\n\n  private ProgressThresholdsGroup buildThresholdsGroup(boolean entering) {\n    PathMotion pathMotion = getPathMotion();\n    if (pathMotion instanceof ArcMotion || pathMotion instanceof MaterialArcMotion) {\n      return getThresholdsOrDefault(\n          entering, DEFAULT_ENTER_THRESHOLDS_ARC, DEFAULT_RETURN_THRESHOLDS_ARC);\n    } else {\n      return getThresholdsOrDefault(entering, DEFAULT_ENTER_THRESHOLDS, DEFAULT_RETURN_THRESHOLDS);\n    }\n  }\n\n  private ProgressThresholdsGroup getThresholdsOrDefault(\n      boolean entering,\n      ProgressThresholdsGroup defaultEnterThresholds,\n      ProgressThresholdsGroup defaultReturnThresholds) {\n    ProgressThresholdsGroup defaultThresholds =","sourceCodeStart":1023,"sourceCodeEnd":1059,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/transition/MaterialContainerTransform.java#L1023-L1059","documentation":"MaterialContainerTransform.isEntering (MaterialContainerTransform.java:1041) interprets the configured transition direction to decide whether the animation plays as enter or return. TRANSITION_DIRECTION_AUTO compares start/end areas, ENTER and RETURN force the direction; any other int throws IllegalArgumentException. The value originates from setTransitionDirection().","triggerScenarios":"Calling transform.setTransitionDirection(v) with a value other than TRANSITION_DIRECTION_AUTO/ENTER/RETURN and starting the transition; restoring a direction from persistence with a stale or invalid number.","commonSituations":"Hardcoded numeric direction; constants confused with fade/fit mode ints; version migration where saved ints no longer map to valid constants.","solutions":["Use MaterialContainerTransform.TRANSITION_DIRECTION_AUTO / TRANSITION_DIRECTION_ENTER / TRANSITION_DIRECTION_RETURN.","Validate persisted/dynamic values: if not one of the three constants, fall back to TRANSITION_DIRECTION_AUTO.","Annotate wrapper APIs with @TransitionDirection to get compile-time constant checking."],"exampleFix":"// before\ntransform.setTransitionDirection(5);\n\n// after\ntransform.setTransitionDirection(MaterialContainerTransform.TRANSITION_DIRECTION_ENTER);","handlingStrategy":"validation","validationCode":"static @TransitionDirection int coerceDirection(int d) {\n  return (d == MaterialContainerTransform.TRANSITION_DIRECTION_AUTO\n       || d == MaterialContainerTransform.TRANSITION_DIRECTION_ENTER\n       || d == MaterialContainerTransform.TRANSITION_DIRECTION_RETURN)\n      ? d : MaterialContainerTransform.TRANSITION_DIRECTION_AUTO;\n}\ntransform.setTransitionDirection(coerceDirection(savedDir));","typeGuard":"static boolean isValidTransitionDirection(int d) {\n  return d >= MaterialContainerTransform.TRANSITION_DIRECTION_AUTO\n      && d <= MaterialContainerTransform.TRANSITION_DIRECTION_RETURN;\n}","tryCatchPattern":null,"preventionTips":["Pass only TRANSITION_DIRECTION_* constants.","Validate at set-time in a wrapper so failures surface at the call site, not during the animation.","Prefer AUTO and let the transform compare areas instead of hardcoding a direction."],"tags":["android","material-components","container-transform","transition-direction","enum-validation"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}