{"record":{"id":"5873361d5717053f","repo":"airbnb/epoxy","slug":"you-cannot-call-requestmodelbuild-directly-call-setdata-587336","errorCode":null,"errorMessage":"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a model refresh with new data.","messagePattern":"You cannot call `requestModelBuild` directly\\. Call `setData` instead to trigger a model refresh with new data\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"epoxy-adapter/src/main/java/com/airbnb/epoxy/Typed4EpoxyController.java","lineNumber":51,"sourceCode":"\n  /**\n   * Call this with the latest data when you want models to be rebuilt. The data will be passed on\n   * to {@link #buildModels(Object, Object, Object, Object)}\n   */\n  public void setData(T data1, U data2, V data3, W data4) {\n    this.data1 = data1;\n    this.data2 = data2;\n    this.data3 = data3;\n    this.data4 = data4;\n    allowModelBuildRequests = true;\n    requestModelBuild();\n    allowModelBuildRequests = false;\n  }\n\n  @Override\n  public final void requestModelBuild() {\n    if (!allowModelBuildRequests) {\n      throw new IllegalStateException(\n          \"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a \"\n              + \"model refresh with new data.\");\n    }\n    super.requestModelBuild();\n  }\n\n  @Override\n  public void moveModel(int fromPosition, int toPosition) {\n    allowModelBuildRequests = true;\n    super.moveModel(fromPosition, toPosition);\n    allowModelBuildRequests = false;\n  }\n\n  @Override\n  public void requestDelayedModelBuild(int delayMs) {\n    if (!allowModelBuildRequests) {\n      throw new IllegalStateException(\n          \"You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a \"","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/airbnb/epoxy/blob/e45bd3a61fe3a1f130e184f5b8dcf172ab99025a/epoxy-adapter/src/main/java/com/airbnb/epoxy/Typed4EpoxyController.java#L33-L69","documentation":"Typed4EpoxyController finalizes `requestModelBuild()` and throws `IllegalStateException` unless `allowModelBuildRequests` is true, which is only the case transiently inside `setData(data1, data2, data3, data4)`. This enforces the Typed-controller contract: model rebuilds always accompany fresh data so all four data fields and the models stay in sync.","triggerScenarios":"Calling `controller.requestModelBuild()` directly, e.g. after mutating one of the four data objects in place or after an async update, instead of calling `setData` with new values.","commonSituations":"Porting refresh logic from plain `EpoxyController` to a Typed4 controller; pushing only some of the four data pieces and hoping a rebuild picks them up; triggering rebuilds from a presenter after network callbacks.","solutions":["Call `controller.setData(newData1, newData2, newData3, newData4)` with all four current values.","Keep the authoritative data in the owning screen and re-submit the full tuple on every change.","Use base `EpoxyController` if manual rebuild control is genuinely needed.","Make `buildModels(data1, data2, data3, data4)` depend only on its parameters so re-submission is idempotent."],"exampleFix":"// before\ncontroller.requestModelBuild(); // IllegalStateException\n\n// after\ncontroller.setData(latestData1, latestData2, latestData3, latestData4);","handlingStrategy":"validation","validationCode":"// Typed4EpoxyController: refresh only via setData\ncontroller.setData(newData1, newData2, newData3, newData4);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass all four data values when refreshing a Typed4 controller.","Keep an authoritative copy of the data tuple in the owning screen.","Remove any requestModelBuild calls left over from migration."],"tags":["android","epoxy","lifecycle","api-misuse"],"backgroundTag":"unsupported-operation","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"}