{"record":{"id":"7a48118731e895f6","repo":"apache/dubbo","slug":"not-all-application-models-are-completely-destroye","errorCode":null,"errorMessage":"Not all application models are completely destroyed, remaining <remainApplications.size()> application models may be created during destruction: <remainApplications>","messagePattern":"Not all application models are completely destroyed, remaining <remainApplications\\.size\\(\\)> application models may be created during destruction: <remainApplications>","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java","lineNumber":158,"sourceCode":"            }\n\n            // remove from allInstances and reset default FrameworkModel\n            synchronized (globalLock) {\n                allInstances.remove(this);\n                resetDefaultFrameworkModel();\n            }\n\n            // if all FrameworkModels are destroyed, clean global static resources, shutdown dubbo completely\n            destroyGlobalResources();\n        }\n    }\n\n    private void checkApplicationDestroy() {\n        synchronized (instLock) {\n            if (applicationModels.size() > 0) {\n                List<String> remainApplications =\n                        applicationModels.stream().map(ScopeModel::getDesc).collect(Collectors.toList());\n                throw new IllegalStateException(\n                        \"Not all application models are completely destroyed, remaining \" + remainApplications.size()\n                                + \" application models may be created during destruction: \" + remainApplications);\n            }\n        }\n    }\n\n    private void destroyGlobalResources() {\n        synchronized (globalLock) {\n            if (allInstances.isEmpty()) {\n                GlobalResourcesRepository.getInstance().destroy();\n            }\n        }\n    }\n\n    /**\n     * During destroying the default FrameworkModel, the FrameworkModel.defaultModel() or ApplicationModel.defaultModel()\n     * will return a broken model, maybe cause unpredictable problem.\n     * Recommendation: Avoid using the default model as much as possible.","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/FrameworkModel.java#L140-L176","documentation":"Thrown by FrameworkModel.checkApplicationDestroy during framework destruction when one or more ApplicationModels still exist. A FrameworkModel can only finish destroying its global resources when all child ApplicationModels are gone; leftover applications (sometimes created mid-teardown) abort the process.","triggerScenarios":"FrameworkModel destroy sequence runs checkApplicationDestroy() and finds applicationModels.size() > 0. Happens when an ApplicationModel is created during the destruction window or was never properly destroyed first.","commonSituations":"An async task or lazy initializer spins up a new ApplicationModel while the framework is shutting down. Misordered shutdown where the FrameworkModel is destroyed before all its ApplicationModels. Static/singleton code that auto-creates an application on access during teardown. Test frameworks that leak application models across tests.","solutions":["Destroy all ApplicationModels before destroying the FrameworkModel; respect the teardown order.","Stop/quiesce any background tasks that may lazily create ApplicationModels before starting shutdown.","In tests, use Dubbo's test utilities to fully reset models and avoid leaking applications across cases.","Audit static singletons or auto-initializers that can create an ApplicationModel during destruction."],"exampleFix":"// before\nframeworkModel.destroy(); // applicationModels not yet cleared -> throws\n\n// after\nfor (ApplicationModel app : frameworkModel.getApplicationModels()) {\n    app.destroy();\n}\nframeworkModel.destroy();","handlingStrategy":"validation","validationCode":"// Ensure all application models are gone before destroying the framework\nList<ApplicationModel> remaining = new ArrayList<>(frameworkModel.getApplicationModels());\nfor (ApplicationModel app : remaining) {\n    if (!app.isDestroyed()) app.destroy();\n}\nif (!frameworkModel.getApplicationModels().isEmpty()) {\n    throw new IllegalStateException(\n        \"Cannot destroy FrameworkModel: \"\n            + frameworkModel.getApplicationModels() + \" still present\");\n}\nframeworkModel.destroy();","typeGuard":null,"tryCatchPattern":"try {\n    frameworkModel.destroy();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Not all application models are completely destroyed\")) {\n        // explicitly destroy leftover ApplicationModels first, then retry\n    }\n    throw e;\n}","preventionTips":["Always destroy child ApplicationModels before the parent FrameworkModel.","Stop background tasks that can lazily create ApplicationModels before teardown.","Use Dubbo-provided test reset utilities to avoid model leaks across tests.","Audit static singletons that auto-initialize ApplicationModels."],"tags":["lifecycle","scope-model","shutdown","framework"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}