{"record":{"id":"d126ba3828bd9c32","repo":"airbnb/epoxy","slug":"diffing-was-already-enabled","errorCode":null,"errorMessage":"Diffing was already enabled","messagePattern":"Diffing was already enabled","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyAdapter.java","lineNumber":44,"sourceCode":"   * are responsible for notifying data changes whenever this list is changed.\n   */\n  protected final List<EpoxyModel<?>> models = new ModelList();\n  private DiffHelper diffHelper;\n\n  @Override\n  List<EpoxyModel<?>> getCurrentModels() {\n    return models;\n  }\n\n  /**\n   * Enables support for automatically notifying model changes via {@link #notifyModelsChanged()}.\n   * If used, this should be called in the constructor, before any models are changed.\n   *\n   * @see #notifyModelsChanged()\n   */\n  protected void enableDiffing() {\n    if (diffHelper != null) {\n      throw new IllegalStateException(\"Diffing was already enabled\");\n    }\n\n    if (!models.isEmpty()) {\n      throw new IllegalStateException(\"You must enable diffing before modifying models\");\n    }\n\n    if (!hasStableIds()) {\n      throw new IllegalStateException(\"You must have stable ids to use diffing\");\n    }\n\n    diffHelper = new DiffHelper(this, false);\n  }\n\n  @Override\n  EpoxyModel<?> getModelForPosition(int position) {\n    EpoxyModel<?> model = models.get(position);\n    return model.isShown() ? model : hiddenModel;\n  }","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/airbnb/epoxy/blob/e45bd3a61fe3a1f130e184f5b8dcf172ab99025a/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyAdapter.java#L26-L62","documentation":"EpoxyAdapter.enableDiffing() throws IllegalStateException if diffHelper is already non-null, meaning enableDiffing() was called twice. The helper registers an observer; double registration would duplicate diff work and notifications, so it is disallowed.","triggerScenarios":"Calling enableDiffing() more than once on the same adapter instance — e.g. in a constructor that a subclass also calls, or re-invoking it after reconfiguration.","commonSituations":"Base-class constructor calls enableDiffing() and a subclass constructor calls it again; developer adds the call defensively in an init path that runs repeatedly (adapter reuse/rebind).","solutions":["Call enableDiffing() exactly once, in the adapter's constructor","If unsure, guard the call: only call when diffHelper is not yet enabled (use a subclass flag if diffHelper is inaccessible)","Remove duplicate calls in subclass constructors where the superclass already enables diffing"],"exampleFix":"// before\npublic MyAdapter() {\n  super();\n  enableDiffing(); // super already called it\n}\n\n// after\npublic MyAdapter() {\n  super(); // superclass constructor calls enableDiffing() once\n}","handlingStrategy":"validation","validationCode":"// enable diffing only once\nif (!diffingEnabled) { enableDiffing(); diffingEnabled = true; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call enableDiffing() exactly once, in the constructor","Don't re-enable in subclasses if the superclass already does","Keep adapter configuration in one place"],"tags":["android","epoxy","diffing","initialization"],"backgroundTag":"invalid-state-transition","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"}