{"record":{"id":"d49daeda4e9843c6","repo":"airbnb/epoxy","slug":"models-cannot-be-empty","errorCode":null,"errorMessage":"Models cannot be empty","messagePattern":"Models cannot be empty","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelGroup.java","lineNumber":93,"sourceCode":"  public EpoxyModelGroup(@LayoutRes int layoutRes, Collection<? extends EpoxyModel<?>> models) {\n    this(layoutRes, new ArrayList<>(models));\n  }\n\n  /**\n   * @param layoutRes The layout to use with these models.\n   * @param models    The models that will be used to bind the views in the given layout.\n   */\n  public EpoxyModelGroup(@LayoutRes int layoutRes, EpoxyModel<?>... models) {\n    this(layoutRes, new ArrayList<>(Arrays.asList(models)));\n  }\n\n  /**\n   * @param layoutRes The layout to use with these models.\n   * @param models    The models that will be used to bind the views in the given layout.\n   */\n  private EpoxyModelGroup(@LayoutRes int layoutRes, List<EpoxyModel<?>> models) {\n    if (models.isEmpty()) {\n      throw new IllegalArgumentException(\"Models cannot be empty\");\n    }\n\n    this.models = models;\n    layout(layoutRes);\n    id(models.get(0).id());\n\n    boolean saveState = false;\n    for (EpoxyModel<?> model : models) {\n      if (model.shouldSaveViewState()) {\n        saveState = true;\n        break;\n      }\n    }\n    // By default we save view state if any of the models need to save state.\n    shouldSaveViewStateDefault = saveState;\n  }\n\n  /**","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/airbnb/epoxy/blob/e45bd3a61fe3a1f130e184f5b8dcf172ab99025a/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelGroup.java#L75-L111","documentation":"An EpoxyModelGroup wraps a set of models and binds them into one layout; with zero models there is nothing to bind and no id to inherit (it takes the id of the first model), so the private constructor throws IllegalArgumentException for an empty list.","triggerScenarios":"Constructing an EpoxyModelGroup (or using withModels builders that delegate to it) with an empty List<EpoxyModel<?>>.","commonSituations":"Building groups from filtered/empty data lists without checking size; grouping sub-lists where a page may return zero items.","solutions":["Check that the list is non-empty before constructing the group, or skip adding the group entirely","Add a placeholder/empty-state model instead of an empty group","Guard builder code paths that construct groups from dynamic data"],"exampleFix":"// before\nadd(new EpoxyModelGroup_(R.layout.group).models(subList)); // throws when empty\n// after\nif (!subList.isEmpty()) { add(new EpoxyModelGroup_(R.layout.group).models(subList)); }","handlingStrategy":"validation","validationCode":"if (models == null || models.isEmpty()) { return; } // skip group","typeGuard":"if (!(models instanceof List) || ((List<?>) models).isEmpty()) return;","tryCatchPattern":"try { add(new EpoxyModelGroup_(layout).models(models)); } catch (IllegalArgumentException e) { Log.w(TAG, \"Empty group skipped\"); }","preventionTips":["Check list size before grouping","Render an empty-state model instead of an empty group"],"tags":["android","epoxy","empty-list","validation"],"backgroundTag":"empty-required-field","analyzedSha":"e45bd3a61fe3a1f130e184f5b8dcf172ab99025a","analyzedAt":"2026-09-13T03:24:16.052Z","contentChangedAt":"2026-09-13T03:24:16.052Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}