{"record":{"id":"e7269ca8eb77b462","repo":"airbnb/epoxy","slug":"a-controller-must-be-set-before-requesting-a-model-build","errorCode":null,"errorMessage":"A controller must be set before requesting a model build.","messagePattern":"A controller must be set before requesting a model build\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyRecyclerView.kt","lineNumber":535,"sourceCode":"        /**\n         * Analagous to [EpoxyController.buildModels]. You should create new model instances and\n         * add them to the given controller. [AutoModel] cannot be used with models added this\n         * way.\n         */\n        fun buildModels(controller: EpoxyController)\n    }\n\n    /**\n     * Request that the currently set EpoxyController has its models rebuilt. You can use this to\n     * avoid saving your controller as a field.\n     *\n     * You cannot use this if your controller is a [TypedEpoxyController] or if you set\n     * models via [setModels]. In that case you must set data directly on the\n     * controller or set models again.\n     */\n    fun requestModelBuild() {\n        if (epoxyController == null) {\n            throw IllegalStateException(\"A controller must be set before requesting a model build.\")\n        }\n\n        if (epoxyController is SimpleEpoxyController) {\n            throw IllegalStateException(\"Models were set with #setModels, they can not be rebuilt.\")\n        }\n\n        epoxyController!!.requestModelBuild()\n    }\n\n    /**\n     * Clear the currently set EpoxyController or Adapter as well as any models that are displayed.\n     *\n     * Any pending requests to the EpoxyController to build models are canceled.\n     *\n     * Any existing child views are recycled to the view pool.\n     */\n    open fun clear() {\n        // The controller is cleared so the next time models are set we can create a fresh one.","sourceCodeStart":517,"sourceCodeEnd":553,"githubUrl":"https://github.com/airbnb/epoxy/blob/e45bd3a61fe3a1f130e184f5b8dcf172ab99025a/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyRecyclerView.kt#L517-L553","documentation":"EpoxyRecyclerView.requestModelBuild() rebuilds models via the controller previously set with withModels/buildModelsWith. If no controller was ever set, it throws this IllegalStateException instead of failing silently.","triggerScenarios":"Calling recyclerView.requestModelBuild() when epoxyController is null — i.e., models were never provided via withModels/buildModelsWith, or you used setModels directly.","commonSituations":"Calling requestModelBuild on a RecyclerView where models were supplied via setModels; calling before withModels has run; using it with TypedEpoxyController flows that never attach through withModels.","solutions":["Set a controller first with recyclerView.withModels { ... } or buildModelsWith","If you used setModels, re-call setModels with fresh models instead of requestModelBuild","For TypedEpoxyController, call setData on the controller directly"],"exampleFix":"// before\nrecyclerView.requestModelBuild(); // no controller set\n// after\nrecyclerView.withModels {\n  add(model)\n}\n// or, if using setModels:\nrecyclerView.setModels(buildModelList());","handlingStrategy":"validation","validationCode":"if (recyclerView.epoxyController != null) recyclerView.requestModelBuild() else setModelsOrWithData()","typeGuard":"val canRequestBuild: Boolean get() = recyclerView.epoxyController != null && recyclerView.epoxyController !is SimpleEpoxyController","tryCatchPattern":"try { recyclerView.requestModelBuild() } catch (e: IllegalStateException) { recyclerView.withModels { /* rebuild */ } }","preventionTips":["Always call withModels/buildModelsWith before requestModelBuild","Check epoxyController nullability before refreshing","For setModels flows, re-call setModels instead"],"tags":["android","epoxy","illegal-state","api-misuse"],"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"}