{"record":{"id":"43d10d5e3547cc01","repo":"nopSolutions/nopCommerce","slug":"topic-not-found","errorCode":null,"errorMessage":"Topic not found","messagePattern":"Topic not found","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"warning","filePath":"src/Presentation/Nop.Web/Areas/Admin/Factories/MenuModelFactory.cs","lineNumber":144,"sourceCode":"\n        try\n        {\n            switch ((MenuItemType)model.MenuItemTypeId)\n            {\n                case MenuItemType.Product:\n                {\n                    var product = await _productService.GetProductByIdAsync(entityId);\n\n                    if (product is null || product.Deleted)\n                        throw new NopException(\"Product not found\");\n\n                    model.ProductName = product.Name;\n                    model.ProductId = product.Id;\n                    break;\n                }\n                case MenuItemType.TopicPage:\n                {\n                    var topic = await _topicService.GetTopicByIdAsync(entityId) ?? throw new NopException(\"Topic not found\");\n                    model.TopicId = topic.Id;\n                    break;\n                }\n                case MenuItemType.Category:\n                {\n                    var category = await _categoryService.GetCategoryByIdAsync(entityId);\n\n                    if (category is null || category.Deleted)\n                        throw new NopException(\"Category not found\");\n\n                    model.CategoryId = category.Id;\n                    break;\n                }\n                case MenuItemType.Vendor:\n                {\n                    var vendor = await _vendorService.GetVendorByIdAsync(entityId);\n\n                    if (vendor is null || vendor.Deleted)","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Presentation/Nop.Web/Areas/Admin/Factories/MenuModelFactory.cs#L126-L162","documentation":"Thrown by InitMenuItemModelEntityIdAsync while building an admin menu item model. When a menu item is of type TopicPage, the factory resolves the linked topic via _topicService.GetTopicByIdAsync(entityId); if that returns null the topic record does not exist (deleted, wrong id, or never created) and a NopException is thrown. It is caught locally (line 182) and surfaced only as a UI warning notification, so it does not crash the request. It signals a dangling entity reference: the menu item points at a topic id that the database can no longer resolve.","triggerScenarios":"A MenuItem row exists with MenuItemTypeId = TopicPage and an EntityId value for which TopicService.GetTopicByIdAsync returns null. This happens when the linked topic was deleted after the menu item was created, when an admin hand-edited/seeded a bad EntityId, or during import where topic ids were remapped.","commonSituations":"Migrating/importing menus where topic ids shift; deleting a topic that is still referenced by a menu; multi-store setups where the topic exists in another store context; stale menu items left after a topic cleanup script.","solutions":["Re-open the menu item in the admin UI and re-select a valid topic (the warning is shown and the item is not broken for editing).","If the topic was deleted by mistake, restore it from a backup so the EntityId resolves again.","Run a data-integrity query to find menu items whose TopicPage EntityId no longer matches a row in Topic, and clear or reassign them.","Before deleting a topic, remove or reassign any menu items that reference it."],"exampleFix":"// before\nvar topic = await _topicService.GetTopicByIdAsync(entityId) ?? throw new NopException(\"Topic not found\");\n// after (graceful: skip and warn only)\nvar topic = await _topicService.GetTopicByIdAsync(entityId);\nif (topic is null)\n{\n    _notificationService.WarningNotification($\"Topic with id {entityId} was not found; menu item skipped.\");\n    return;\n}\nmodel.TopicId = topic.Id;","handlingStrategy":"validation","validationCode":"// Before building the menu item model, verify the topic exists.\nif (model.MenuItemTypeId == (int)MenuItemType.TopicPage)\n{\n    var topic = await _topicService.GetTopicByIdAsync(entityId);\n    if (topic is null)\n    {\n        _notificationService.WarningNotification($\"Topic {entityId} not found; skipping.\");\n        return;\n    }\n}","typeGuard":"// C# has no runtime type guard; use a null check on the loaded entity.\nstatic bool TopicExists(Topic t) => t is not null;","tryCatchPattern":"// The factory already catches NopException and shows a warning:\ntry { /* InitMenuItemModelEntityIdAsync body */ }\ncatch (NopException ex) { _notificationService.WarningNotification(ex.Message); }","preventionTips":["Before deleting a topic, remove or reassign menu items that reference it.","Run a periodic referential-integrity check between menu items and their target entities.","Validate entityId against the target table during menu-item save, not only at render time."],"tags":["nopcommerce","admin","menu","topic","data-integrity","null-reference"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}