{"record":{"id":"9c1173e7efa1f98e","repo":"nopSolutions/nopCommerce","slug":"you-cannot-delete-the-only-configured-store","errorCode":null,"errorMessage":"You cannot delete the only configured store","messagePattern":"You cannot delete the only configured store","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Libraries/Nop.Services/Stores/StoreService.cs","lineNumber":69,"sourceCode":"        return parsedValues.ToArray();\r\n    }\r\n\r\n    #endregion\r\n\r\n    #region Methods\r\n\r\n    /// <summary>\r\n    /// Deletes a store\r\n    /// </summary>\r\n    /// <param name=\"store\">Store</param>\r\n    /// <returns>A task that represents the asynchronous operation</returns>\r\n    public virtual async Task DeleteStoreAsync(Store store)\r\n    {\r\n        ArgumentNullException.ThrowIfNull(store);\r\n\r\n        var allStores = await GetAllStoresAsync();\r\n        if (allStores.Count == 1)\r\n            throw new Exception(\"You cannot delete the only configured store\");\r\n\r\n        await _storeRepository.DeleteAsync(store);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Gets all stores\r\n    /// </summary>\r\n    /// <returns>\r\n    /// A task that represents the asynchronous operation\r\n    /// The task result contains the stores\r\n    /// </returns>\r\n    public virtual async Task<IList<Store>> GetAllStoresAsync()\r\n    {\r\n        return await _storeRepository.GetAllAsync(query =>\r\n        {\r\n            return from s in query orderby s.DisplayOrder, s.Id select s;\r\n        }, _ => default, includeDeleted: false);\r\n    }\r","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Stores/StoreService.cs#L51-L87","documentation":"Thrown by StoreService.DeleteStoreAsync as a business-rule guard: it loads all stores and refuses to delete if there is exactly one. nopCommerce requires at least one store to remain so that requests always resolve to a store context.","triggerScenarios":"An admin or API call attempts to delete the sole remaining store record in the Store table. Reachable via the admin store management UI or any code path calling IStoreService.DeleteStoreAsync when GetAllStoresAsync().Count == 1.","commonSituations":"Cleaning up test stores and deleting the last one; single-store setup where someone tries to remove the default store; automation/script that deletes all stores in a loop.","solutions":["Create a second store first, then delete the original — never leave zero stores.","If you truly want a different primary store, add the new one, re-point configurations to it, then delete the old one.","If deleting programmatically, guard with: if ((await _storeService.GetAllStoresAsync()).Count > 1) await DeleteStoreAsync(...)."],"exampleFix":"// before\nawait _storeService.DeleteStoreAsync(onlyStore); // throws\n// after\nawait _storeService.InsertStoreAsync(newStore);\n// ...migrate config/URL bindings...\nawait _storeService.DeleteStoreAsync(onlyStore);","handlingStrategy":"validation","validationCode":"var stores = await _storeService.GetAllStoresAsync();\nif (stores.Count <= 1) return BadRequest(\"Create another store before deleting this one.\");\nawait _storeService.DeleteStoreAsync(store);","typeGuard":"static bool CanDeleteStore(IList<Store> all) => all.Count > 1;","tryCatchPattern":"try { await _storeService.DeleteStoreAsync(store); }\ncatch (Exception ex) when (ex.Message.Contains(\"only configured store\"))\n{ ModelState.AddModelError(string.Empty, \"You cannot delete the only store.\"); }","preventionTips":["Disable the delete button in the UI when only one store remains.","In automation, count stores before deleting.","Always provision a replacement store first."],"tags":["stores","business-rule","validation","multi-store"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}