{"record":{"id":"4d96b1eb766d6522","repo":"nopSolutions/nopCommerce","slug":"product-id-sci-productid-cannot-be-loaded","errorCode":null,"errorMessage":"Product (Id={sci.ProductId}) cannot be loaded","messagePattern":"Product \\(Id=(.+?)\\) cannot be loaded","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Libraries/Nop.Services/Orders/ShoppingCartService.cs","lineNumber":1945,"sourceCode":"    /// <returns>\r\n    /// A task that represents the asynchronous operation\r\n    /// The task result contains the error (if exists); otherwise, empty string. Cycle length. Cycle period. Total cycles\r\n    /// </returns>\r\n    public virtual async Task<(string error, int cycleLength, RecurringProductCyclePeriod cyclePeriod, int totalCycles)> GetRecurringCycleInfoAsync(IList<ShoppingCartItem> shoppingCart)\r\n    {\r\n        var rezCycleLength = 0;\r\n        RecurringProductCyclePeriod rezCyclePeriod = 0;\r\n        var rezTotalCycles = 0;\r\n\r\n        int? cycleLength = null;\r\n        RecurringProductCyclePeriod? cyclePeriod = null;\r\n        int? totalCycles = null;\r\n\r\n        var conflictError = await _localizationService.GetResourceAsync(\"ShoppingCart.ConflictingShipmentSchedules\");\r\n\r\n        foreach (var sci in shoppingCart)\r\n        {\r\n            var product = await _productService.GetProductByIdAsync(sci.ProductId) ?? throw new NopException($\"Product (Id={sci.ProductId}) cannot be loaded\");\r\n\r\n            if (!product.IsRecurring)\r\n                continue;\r\n\r\n            //cycle length\r\n            if (cycleLength.HasValue && cycleLength.Value != product.RecurringCycleLength)\r\n                return (conflictError, rezCycleLength, rezCyclePeriod, rezTotalCycles);\r\n            cycleLength = product.RecurringCycleLength;\r\n\r\n            //cycle period\r\n            if (cyclePeriod.HasValue && cyclePeriod.Value != product.RecurringCyclePeriod)\r\n                return (conflictError, rezCycleLength, rezCyclePeriod, rezTotalCycles);\r\n            cyclePeriod = product.RecurringCyclePeriod;\r\n\r\n            //total cycles\r\n            if (totalCycles.HasValue && totalCycles.Value != product.RecurringTotalCycles)\r\n                return (conflictError, rezCycleLength, rezCyclePeriod, rezTotalCycles);\r\n            totalCycles = product.RecurringTotalCycles;\r","sourceCodeStart":1927,"sourceCodeEnd":1963,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Orders/ShoppingCartService.cs#L1927-L1963","documentation":"Thrown by ShoppingCartService while validating recurring shipment schedules when GetProductByIdAsync(sci.ProductId) returns null. The cart item references a product that cannot be loaded from the database. This is a referential-integrity break: the ShoppingCartItem exists but its Product is missing, so recurring-cycle validation cannot read product.IsRecurring / cycle fields and aborts.","triggerScenarios":"Adding to / validating a cart that contains a ShoppingCartItem whose ProductId points to a deleted, purged, or non-existent product, while the cart is being checked for recurring-schedule conflicts. Reachable during AddToCart, cart validation, and checkout when a recurring product is involved.","commonSituations":"A product was deleted (soft/hard) but cart items still reference it; a botched import/migration; a test that seeds a cart item without the product; caching a stale ProductId after the product was removed.","solutions":["Run a data-integrity check for cart items whose ProductId has no matching product and clean them up.","Before cart operations, ensure products referenced by active cart items are not hard-deleted; prefer soft-delete/Hide or remove cart items on product delete.","Fix the test/import to insert the Product in the same transaction as the cart item.","Catch NopException around the recurring validation call, log sci.Id/ProductId, and remove the offending cart item with a user-facing message."],"exampleFix":"// before\nvar (warnings, _, _, _) = await _shoppingCartService.GetRecurringCycleInfoAsync(cart);\n\n// after\nforeach (var sci in cart)\n{\n    var p = await _productService.GetProductByIdAsync(sci.ProductId);\n    if (p is null)\n    {\n        await _shoppingCartService.DeleteShoppingCartItemAsync(sci.Id, ensureOnlyActiveCheckoutAttributes: false);\n        continue;\n    }\n}\nvar (warnings, _, _, _) = await _shoppingCartService.GetRecurringCycleInfoAsync(cart);","handlingStrategy":"validation","validationCode":"foreach (var sci in cart)\n{\n    var p = await _productService.GetProductByIdAsync(sci.ProductId);\n    if (p is null)\n    {\n        await _shoppingCartService.DeleteShoppingCartItemAsync(sci.Id, ensureOnlyActiveCheckoutAttributes: false);\n        cart = cart.Where(x => x.Id != sci.Id).ToList();\n    }\n}","typeGuard":null,"tryCatchPattern":"try { await _shoppingCartService.GetRecurringCycleInfoAsync(cart); }\ncatch (NopException ex) when (ex.Message.Contains(\"cannot be loaded\"))\n{\n    // a cart item references a missing product; log and remove offending items\n    _logger.LogError(ex, \"Cart references a missing product\");\n}","preventionTips":["Do not hard-delete products that cart items still reference; soft-delete or remove the cart items first.","Run periodic integrity checks for cart items with no matching product.","Seed products in the same transaction as cart items in tests."],"tags":["shopping-cart","product","data-integrity","recurring"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}