MuntashirAkon/AppManager · error · IllegalArgumentException

STATE_DRAGGING should not be set externally.|STATE_SETTLING…

Error message

STATE_DRAGGING should not be set externally.|STATE_SETTLING should not be set externally.

What it means

setState() only accepts stable states (COLLAPSED, EXPANDED, HIDDEN, HALF_EXPANDED). STATE_DRAGGING and STATE_SETTLING are transient internal states managed by the drag helper; setting them externally is invalid, so the behavior throws IllegalArgumentException naming the offending state.

Solutions

  1. Only pass stable states (COLLAPSED/EXPANDED/HIDDEN/HALF_EXPANDED)
  2. Filter transient states out before calling setState, e.g. skip DRAGGING/SETTLING
  3. Let the behavior's internal drag controller manage transient states

Example fix

// before
behavior.setState(savedState);
// after
if (savedState != STATE_DRAGGING && savedState != STATE_SETTLING) {
    behavior.setState(savedState);
}
Defensive patterns

Strategy: validation

Validate before calling

if (state != STATE_DRAGGING && state != STATE_SETTLING) behavior.setState(state);

Type guard

boolean isStableState(int s) { return s == STATE_COLLAPSED || s == STATE_EXPANDED || s == STATE_HIDDEN || s == STATE_HALF_EXPANDED; }

Try / catch

try {
    behavior.setState(state);
} catch (IllegalArgumentException e) {
    // ignore transient states
}

Prevention

When it happens

Trigger: Calling behavior.setState(BottomSheetBehavior.STATE_DRAGGING) or setState(STATE_SETTLING), or passing an int variable that happens to hold a transient state.

Common situations: Persistence/restore code saving state as an int and re-applying it; loops iterating over all STATE_* constants; animating by setting dragging state manually.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/e9d1acbd05a87b59. Report an issue: GitHub.

Appendix: source

Thrown at libcore/ui/src/main/java/io/github/muntashirakon/dialog/BottomSheetBehavior.java:1316

    /**
     * Removes a previously added callback.
     *
     * @param callback The callback to remove.
     */
    public void removeBottomSheetCallback(@NonNull BottomSheetCallback callback) {
        callbacks.remove(callback);
    }

    /**
     * Sets the state of the bottom sheet. The bottom sheet will transition to that state with
     * animation.
     *
     * @param state One of {@link #STATE_COLLAPSED}, {@link #STATE_EXPANDED}, {@link #STATE_HIDDEN},
     *     or {@link #STATE_HALF_EXPANDED}.
     */
    public void setState(@StableState int state) {
        if (state == STATE_DRAGGING || state == STATE_SETTLING) {
            throw new IllegalArgumentException(
                    "STATE_"
                            + (state == STATE_DRAGGING ? "DRAGGING" : "SETTLING")
                            + " should not be set externally.");
        }
        if (!hideable && state == STATE_HIDDEN) {
            Log.w(TAG, "Cannot set state: " + state);
            return;
        }
        final int finalState;
        if (state == STATE_HALF_EXPANDED
                && fitToContents
                && getTopOffsetForState(state) <= fitToContentsOffset) {
            // Skip to the expanded state if we would scroll past the height of the contents.
            finalState = STATE_EXPANDED;
        } else {
            finalState = state;
        }
        if (viewRef == null || viewRef.get() == null) {

View on GitHub (pinned to 0152f468fc)