{"record":{"id":"f8863faaaa77870f","repo":"nopSolutions/nopCommerce","slug":"initial-order-could-not-be-loaded","errorCode":null,"errorMessage":"Initial order could not be loaded","messagePattern":"Initial order could not be loaded","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"critical","filePath":"src/Libraries/Nop.Services/Orders/OrderProcessingService.cs","lineNumber":1899,"sourceCode":"    /// Process next recurring payment\r\n    /// </summary>\r\n    /// <param name=\"recurringPayment\">Recurring payment</param>\r\n    /// <param name=\"paymentResult\">Process payment result (info about last payment for automatic recurring payments)</param>\r\n    /// <returns>\r\n    /// A task that represents the asynchronous operation\r\n    /// The task result contains the collection of errors\r\n    /// </returns>\r\n    public virtual async Task<IEnumerable<string>> ProcessNextRecurringPaymentAsync(RecurringPayment recurringPayment, ProcessPaymentResult paymentResult = null)\r\n    {\r\n        ArgumentNullException.ThrowIfNull(recurringPayment);\r\n\r\n        try\r\n        {\r\n            if (!recurringPayment.IsActive)\r\n                throw new NopException(\"Recurring payment is not active\");\r\n\r\n            var initialOrder = await _orderService.GetOrderByIdAsync(recurringPayment.InitialOrderId)\r\n                               ?? throw new NopException(\"Initial order could not be loaded\");\r\n\r\n            var customer = await _customerService.GetCustomerByIdAsync(initialOrder.CustomerId)\r\n                           ?? throw new NopException(\"Customer could not be loaded\");\r\n\r\n            if (await GetNextPaymentDateAsync(recurringPayment) is null)\r\n                throw new NopException(\"Next payment date could not be calculated\");\r\n\r\n            //payment info\r\n            var processPaymentRequest = new ProcessPaymentRequest\r\n            {\r\n                StoreId = initialOrder.StoreId,\r\n                CustomerId = customer.Id,\r\n                OrderGuid = Guid.NewGuid(),\r\n                InitialOrder = initialOrder,\r\n                RecurringCycleLength = recurringPayment.CycleLength,\r\n                RecurringCyclePeriod = recurringPayment.CyclePeriod,\r\n                RecurringTotalCycles = recurringPayment.TotalCycles\r\n            };\r","sourceCodeStart":1881,"sourceCodeEnd":1917,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Orders/OrderProcessingService.cs#L1881-L1917","documentation":"Thrown in ProcessNextRecurringPaymentAsync when _orderService.GetOrderByIdAsync(recurringPayment.InitialOrderId) returns null. The recurring payment references a seed order that no longer exists in the database, so nopCommerce cannot reconstruct the payment context (customer, items, totals) needed for the next cycle.","triggerScenarios":"The initial/seed order was hard-deleted from the Orders table while its RecurringPayment row remains; data corruption; restore from backup that missed the order; manual SQL deletion of orders without cleaning recurring payment records.","commonSituations":"Aggressive order cleanup scripts that delete orders but not related recurring payments; partial DB restore; buggy custom order-purge logic.","solutions":["Restore the missing initial order from backup, or hard-delete the orphaned RecurringPayment record if the subscription is defunct.","Audit order-deletion routines to cascade-clean RecurringPayment rows.","Add a FK/data-integrity check so recurring payments cannot outlive their initial order."],"exampleFix":"// before\nawait _orderService.DeleteOrderAsync(initialOrder); // leaves orphan recurring payment\n\n// after\nforeach (var rp in await _orderService.GetRecurringPaymentsByInitialOrderIdAsync(initialOrder.Id))\n    rp.IsActive = false;\nawait _orderService.UpdateRecurringPaymentAsync(rp);\nawait _orderService.DeleteOrderAsync(initialOrder);","handlingStrategy":"validation","validationCode":"var initialOrder = await _orderService.GetOrderByIdAsync(recurringPayment.InitialOrderId);\nif (initialOrder is null)\n{\n    recurringPayment.IsActive = false; // orphaned - quarantine\n    await _orderService.UpdateRecurringPaymentAsync(recurringPayment);\n    _logger.LogWarning(\"Recurring payment {Id} references deleted initial order {OrderId}\",\n        recurringPayment.Id, recurringPayment.InitialOrderId);\n    return Array.Empty<string>();\n}\n\nreturn await _orderProcessingService.ProcessNextRecurringPaymentAsync(recurringPayment);","typeGuard":"async Task<bool> InitialOrderExistsAsync(RecurringPayment rp)\n    => await _orderService.GetOrderByIdAsync(rp.InitialOrderId) is not null;","tryCatchPattern":"try\n{\n    var errors = await _orderProcessingService.ProcessNextRecurringPaymentAsync(recurringPayment);\n}\ncatch (NopException ex) when (ex.Message == \"Initial order could not be loaded\")\n{\n    recurringPayment.IsActive = false;\n    await _orderService.UpdateRecurringPaymentAsync(recurringPayment);\n    _logger.LogCritical(ex, \"Orphaned recurring payment {Id}\", recurringPayment.Id);\n}","preventionTips":["Cascade-clean RecurringPayment rows when orders are hard-deleted.","Add a referential-integrity check (or DB FK) between RecurringPayment.InitialOrderId and Orders.","Never delete orders via raw SQL without also handling dependent recurring payments."],"tags":["recurring","data-integrity","orphan-record","order","nopcommerce"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}