{"record":{"id":"163bdc1b84bcd339","repo":"nopSolutions/nopCommerce","slug":"no-product-found-with-the-specified-id-163bdc","errorCode":null,"errorMessage":"No product found with the specified id","messagePattern":"No product found with the specified id","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Presentation/Nop.Web/Controllers/BackInStockSubscriptionController.cs","lineNumber":71,"sourceCode":"        _localizationService = localizationService;\n        _notificationService = notificationService;\n        _productService = productService;\n        _storeContext = storeContext;\n        _urlRecordService = urlRecordService;\n        _workContext = workContext;\n    }\n\n    #endregion\n\n    #region Methods\n\n    // Product details page > back in stock subscribe\n    [CheckLanguageSeoCode(ignore: true)]\n    public virtual async Task<IActionResult> SubscribePopup(int productId)\n    {\n        var product = await _productService.GetProductByIdAsync(productId);\n        if (product == null || product.Deleted)\n            throw new ArgumentException(\"No product found with the specified id\");\n\n        var customer = await _workContext.GetCurrentCustomerAsync();\n        var store = await _storeContext.GetCurrentStoreAsync();\n        var model = new BackInStockSubscribeModel\n        {\n            ProductId = product.Id,\n            ProductName = await _localizationService.GetLocalizedAsync(product, x => x.Name),\n            ProductSeName = await _urlRecordService.GetSeNameAsync(product),\n            IsCurrentCustomerRegistered = await _customerService.IsRegisteredAsync(customer),\n            MaximumBackInStockSubscriptions = _catalogSettings.MaximumBackInStockSubscriptions,\n            CurrentNumberOfBackInStockSubscriptions = (await _backInStockSubscriptionService\n                    .GetAllSubscriptionsByCustomerIdAsync(customer.Id, store.Id, 0, 1))\n                .TotalCount\n        };\n        if (product.ManageInventoryMethod == ManageInventoryMethod.ManageStock &&\n            product.BackorderMode == BackorderMode.NoBackorders &&\n            product.AllowBackInStockSubscriptions &&\n            await _productService.GetTotalStockQuantityAsync(product) <= 0)","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Presentation/Nop.Web/Controllers/BackInStockSubscriptionController.cs#L53-L89","documentation":"Thrown in the GET SubscribePopup action of BackInStockSubscriptionController. It loads the product by productId; if the product is null OR its Deleted flag is true it throws ArgumentException. This guards the back-in-stock subscription popup so it never renders for a missing/removed product. Because it throws rather than returning NotFound, the exception propagates to the global handler unless wrapped.","triggerScenarios":"A customer or bot requests the back-in-stock subscribe popup URL with a productId that is deleted (Deleted = true) or absent. Triggered by following an outdated product link, a product removed after the link was indexed, or a crafted/guessed id.","commonSituations":"Search-engine/bot hitting a cached product URL after the product was deleted; customer follows a bookmarked popup link; product soft-deleted between page load and popup open; malformed productId in query string.","solutions":["Return NotFound() or a friendly message instead of throwing ArgumentException for a public-facing popup.","Ensure the product link is removed/redirected when the product is deleted.","Validate productId > 0 and product existence before opening the popup on the client.","Handle bots gracefully so deleted-product popup requests do not throw."],"exampleFix":"// before\nvar product = await _productService.GetProductByIdAsync(productId);\nif (product == null || product.Deleted)\n    throw new ArgumentException(\"No product found with the specified id\");\n// after (return NotFound for a public action)\nvar product = await _productService.GetProductByIdAsync(productId);\nif (product == null || product.Deleted)\n    return NotFound();","handlingStrategy":"validation","validationCode":"// Validate before opening the popup.\nvar product = await _productService.GetProductByIdAsync(productId);\nif (product is null || product.Deleted)\n    return NotFound();","typeGuard":"static bool ProductAvailable(Product p) => p is not null && !p.Deleted;","tryCatchPattern":"// Throwing on a public GET is discouraged; prefer:\nif (product == null || product.Deleted) return NotFound();","preventionTips":["Return NotFound for public-facing popup actions rather than throwing.","Remove/redirect product URLs when the product is soft-deleted.","Validate productId client-side before opening the popup."],"tags":["nopcommerce","public","back-in-stock","product","not-found","soft-delete"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}