{"record":{"id":"07c2b18527e8c573","repo":"material-components/material-components-android","slug":"state-dragging-should-not-be-set-externally","errorCode":null,"errorMessage":"STATE_DRAGGING should not be set externally.","messagePattern":"STATE_DRAGGING should not be set externally\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/bottomsheet/BottomSheetBehavior.java","lineNumber":1478,"sourceCode":"  /**\n   * Removes a previously added callback.\n   *\n   * @param callback The callback to remove.\n   */\n  public void removeBottomSheetCallback(@NonNull BottomSheetCallback callback) {\n    callbacks.remove(callback);\n  }\n\n  /**\n   * Sets the state of the bottom sheet. The bottom sheet will transition to that state with\n   * animation.\n   *\n   * @param state One of {@link #STATE_COLLAPSED}, {@link #STATE_EXPANDED}, {@link #STATE_HIDDEN},\n   *     or {@link #STATE_HALF_EXPANDED}.\n   */\n  public void setState(@StableState int state) {\n    if (state == STATE_DRAGGING || state == STATE_SETTLING) {\n      throw new IllegalArgumentException(\n          \"STATE_\"\n              + (state == STATE_DRAGGING ? \"DRAGGING\" : \"SETTLING\")\n              + \" should not be set externally.\");\n    }\n    if (!hideable && state == STATE_HIDDEN) {\n      Log.w(TAG, \"Cannot set state: \" + state);\n      return;\n    }\n    final int finalState;\n    if (state == STATE_HALF_EXPANDED\n        && fitToContents\n        && getTopOffsetForState(state) <= fitToContentsOffset) {\n      // Skip to the expanded state if we would scroll past the height of the contents.\n      finalState = STATE_EXPANDED;\n    } else {\n      finalState = state;\n    }\n    if (viewRef == null || viewRef.get() == null) {","sourceCodeStart":1460,"sourceCodeEnd":1496,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/bottomsheet/BottomSheetBehavior.java#L1460-L1496","documentation":"BottomSheetBehavior.setState(int) requests a transition to a target state. STATE_DRAGGING and STATE_SETTLING are transient states driven internally by touch events and the drag helper; they cannot be requested externally. Passing either one throws IllegalArgumentException with the offending state name in the message.","triggerScenarios":"Calling setState(BottomSheetBehavior.STATE_DRAGGING) or setState(BottomSheetBehavior.STATE_SETTLING) directly; forwarding a value received via a BottomSheetCallback onStateChanged callback back into setState (callbacks legitimately report DRAGGING/SETTLING).","commonSituations":"Persisting the last reported state and restoring it later with setState — if the app was killed mid-drag the saved state was SETTLING/DRAGGING; 'echo' logic that mirrors state changes between two sheets; switching on state ints and falling into a default branch that calls setState(state).","solutions":["Only call setState with stable states: STATE_COLLAPSED, STATE_EXPANDED, STATE_HALF_EXPANDED, or STATE_HIDDEN.","When persisting state, map transient states to their nearest stable equivalent before saving (e.g. SETTLING -> EXPANDED).","Filter DRAGGING/SETTLING in any callback-forwarding code before re-invoking setState."],"exampleFix":"// before\nbehavior.setBottomSheetCallback(new BottomSheetCallback() {\n  @Override public void onStateChanged(View sheet, int newState) {\n    savedState = newState; // may be STATE_DRAGGING / STATE_SETTLING\n  } ...\n});\nbehavior.setState(savedState); // throws if transient\n\n// after\nprivate static int toStable(int s) {\n  return (s == STATE_DRAGGING || s == STATE_SETTLING) ? STATE_EXPANDED : s;\n}\nbehavior.setState(toStable(savedState));","handlingStrategy":"validation","validationCode":"private static boolean isStableSheetState(int s) {\n  return s == BottomSheetBehavior.STATE_COLLAPSED\n      || s == BottomSheetBehavior.STATE_EXPANDED\n      || s == BottomSheetBehavior.STATE_HALF_EXPANDED\n      || s == BottomSheetBehavior.STATE_HIDDEN;\n}\nif (isStableSheetState(requestedState)) behavior.setState(requestedState);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never echo onStateChanged values straight back into setState.","Map transient states to stable ones before persisting."],"tags":["bottomsheet","illegal-argument","state-machine","callback"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}