{"record":{"id":"776fa221ed2b678e","repo":"airbnb/epoxy","slug":"you-must-set-an-id-on-a-model-before-adding-it-use-the","errorCode":null,"errorMessage":"You must set an id on a model before adding it. Use the @AutoModel annotation if you want an id to be automatically generated for you.","messagePattern":"You must set an id on a model before adding it\\. Use the @AutoModel annotation if you want an id to be automatically generated for you\\.","errorType":"exception","errorClass":"IllegalEpoxyUsage","httpStatus":null,"severity":"error","filePath":"epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyController.java","lineNumber":502,"sourceCode":"   * EpoxyController#buildModels()}.\n   */\n  protected void add(@NonNull List<? extends EpoxyModel<?>> modelsToAdd) {\n    modelsBeingBuilt.ensureCapacity(modelsBeingBuilt.size() + modelsToAdd.size());\n\n    for (EpoxyModel<?> model : modelsToAdd) {\n      add(model);\n    }\n  }\n\n  /**\n   * Method to actually add the model to the list being built. Should be called after all\n   * validations are done.\n   */\n  void addInternal(EpoxyModel<?> modelToAdd) {\n    assertIsBuildingModels();\n\n    if (modelToAdd.hasDefaultId()) {\n      throw new IllegalEpoxyUsage(\n          \"You must set an id on a model before adding it. Use the @AutoModel annotation if you \"\n              + \"want an id to be automatically generated for you.\");\n    }\n\n    if (!modelToAdd.isShown()) {\n      throw new IllegalEpoxyUsage(\n          \"You cannot hide a model in an EpoxyController. Use `addIf` to conditionally add a \"\n              + \"model instead.\");\n    }\n\n    // The model being added may not have been staged if it wasn't mutated before it was added.\n    // In that case we may have a previously staged model that still needs to be added.\n    clearModelFromStaging(modelToAdd);\n    modelToAdd.controllerToStageTo = null;\n    modelsBeingBuilt.add(modelToAdd);\n  }\n\n  /**","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/airbnb/epoxy/blob/e45bd3a61fe3a1f130e184f5b8dcf172ab99025a/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyController.java#L484-L520","documentation":"EpoxyController.addInternal validates every model added during buildModels. A model whose id is still the default (unset) cannot participate in diffing/recycling, so IllegalEpoxyUsage is thrown, pointing you to set an id or use @AutoModel for generated ids.","triggerScenarios":"Calling addTo/addInternal with a model on which .id(...) was never called; forgetting id on a dynamically created model (new FooModel_()); relying on @AutoModel without applying the annotation processor.","commonSituations":"Constructing a generated model class and adding it without chaining .id(); a refactor removing the .id() call; the Epoxy annotation processor not running so @AutoModel fields are not generated/assigned.","solutions":["Call .id(...) with a stable unique value on every model before addTo","Use the @AutoModel annotation on a field and add via that field so an id is generated","Verify the Epoxy annotation processor is configured (kapt/ksp) so @AutoModel works","If id legitimately depends on content, derive it from the bound data (e.g. item.getId())"],"exampleFix":"// before\nnew HeaderModel_(\"Hello\").addTo(this); // crash\n// after\nnew HeaderModel_(\"Hello\").id(\"header\").addTo(this);","handlingStrategy":"validation","validationCode":"if (model.hasDefaultId()) { model.id(computeId()); } model.addTo(controller);","typeGuard":null,"tryCatchPattern":"try { model.addTo(controller); } catch (IllegalEpoxyUsage e) { model.id(uniqueId).addTo(controller); }","preventionTips":["Always chain .id(...) on every generated model before addTo","Use @AutoModel for singleton models and verify kapt/ksp annotation processing is set up","Derive ids from stable data keys so diffs behave correctly"],"tags":["android","epoxy","missing-id","validation"],"backgroundTag":"missing-required-argument","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"}