airbnb/epoxy · error · IllegalStateException

A model was swiped that is not a valid target:

Error message

A model was swiped that is not a valid target: 

What it means

When a swipe gesture completes, onSwiped validates that the swiped model is one the callback can handle via isTouchableModel before invoking onSwipeCompleted. A swipe on any other model type throws IllegalStateException including the model's class, since the callback has no typed swipe handler for it.

Solutions

  1. Update isTouchableModel to accept the model type you want swipable, and implement onSwipeCompleted for it
  2. Disable swiping for non-touchable models by overriding swipe-related enablement per view holder/position
  3. Consume swipes in getSwipeDirs (return 0 for models that are not touchable)

Example fix

// before
@Override public int getSwipeDirs(RecyclerView rv, RecyclerView.ViewHolder vh) { return ItemTouchHelper.LEFT; } // swipes everything
// after
@Override public int getSwipeDirs(RecyclerView rv, RecyclerView.ViewHolder vh) { return isTouchableModel(((EpoxyViewHolder) vh).getModel()) ? ItemTouchHelper.LEFT : 0; }
Defensive patterns

Strategy: type-guard

Validate before calling

if (!touchCallback.isTouchableModel(viewHolder.getModel())) { return 0; } // no swipe dirs

Type guard

if (viewHolder.getModel() instanceof MySwipableModel_) { /* safe to swipe */ }

Try / catch

try { handleSwipe(model, direction); } catch (IllegalStateException e) { Log.e(TAG, "Swiped non-touchable model", e); }

Prevention

When it happens

Trigger: A swipe gesture lands on a model for which isTouchableModel(model) returns false, and onSwiped is invoked with that view holder.

Common situations: ItemTouchHelper swiping enabled for all view types while only some models are swipable; adding new model types to the adapter without updating the touch callback's isTouchableModel; swipe flags not filtered by position/type.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of airbnb/epoxy@e45bd3a61f (2026-09-13). Data as JSON: /api/errors/7cbf0bf487881e1d. Report an issue: GitHub.

Appendix: source

Thrown at epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelTouchCallback.java:102

    //noinspection unchecked
    onModelMoved(fromPosition, toPosition, (T) model, viewHolder.itemView);
    return true;
  }

  @Override
  public void onModelMoved(int fromPosition, int toPosition, T modelBeingMoved, View itemView) {

  }

  @Override
  protected void onSwiped(EpoxyViewHolder viewHolder, int direction) {
    EpoxyModel<?> model = viewHolder.getModel();
    View view = viewHolder.itemView;
    int position = viewHolder.getAdapterPosition();

    if (!isTouchableModel(model)) {
      throw new IllegalStateException(
          "A model was swiped that is not a valid target: " + model.getClass());
    }

    //noinspection unchecked
    onSwipeCompleted((T) model, view, position, direction);
  }

  @Override
  public void onSwipeCompleted(T model, View itemView, int position, int direction) {

  }

  @Override
  protected void onSelectedChanged(@Nullable EpoxyViewHolder viewHolder, int actionState) {
    super.onSelectedChanged(viewHolder, actionState);

    if (viewHolder != null) {
      EpoxyModel<?> model = viewHolder.getModel();

View on GitHub (pinned to e45bd3a61f)