nopSolutions/nopCommerce · critical · NopException
Initial order could not be loaded
Error message
Initial order could not be loaded
What it means
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.
Source
Thrown at src/Libraries/Nop.Services/Orders/OrderProcessingService.cs:1899
/// Process next recurring payment
/// </summary>
/// <param name="recurringPayment">Recurring payment</param>
/// <param name="paymentResult">Process payment result (info about last payment for automatic recurring payments)</param>
/// <returns>
/// A task that represents the asynchronous operation
/// The task result contains the collection of errors
/// </returns>
public virtual async Task<IEnumerable<string>> ProcessNextRecurringPaymentAsync(RecurringPayment recurringPayment, ProcessPaymentResult paymentResult = null)
{
ArgumentNullException.ThrowIfNull(recurringPayment);
try
{
if (!recurringPayment.IsActive)
throw new NopException("Recurring payment is not active");
var initialOrder = await _orderService.GetOrderByIdAsync(recurringPayment.InitialOrderId)
?? throw new NopException("Initial order could not be loaded");
var customer = await _customerService.GetCustomerByIdAsync(initialOrder.CustomerId)
?? throw new NopException("Customer could not be loaded");
if (await GetNextPaymentDateAsync(recurringPayment) is null)
throw new NopException("Next payment date could not be calculated");
//payment info
var processPaymentRequest = new ProcessPaymentRequest
{
StoreId = initialOrder.StoreId,
CustomerId = customer.Id,
OrderGuid = Guid.NewGuid(),
InitialOrder = initialOrder,
RecurringCycleLength = recurringPayment.CycleLength,
RecurringCyclePeriod = recurringPayment.CyclePeriod,
RecurringTotalCycles = recurringPayment.TotalCycles
};
View on GitHub (pinned to 64bdf2ff08)
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.
Example fix
// before
await _orderService.DeleteOrderAsync(initialOrder); // leaves orphan recurring payment
// after
foreach (var rp in await _orderService.GetRecurringPaymentsByInitialOrderIdAsync(initialOrder.Id))
rp.IsActive = false;
await _orderService.UpdateRecurringPaymentAsync(rp);
await _orderService.DeleteOrderAsync(initialOrder); Defensive patterns
Strategy: validation
Validate before calling
var initialOrder = await _orderService.GetOrderByIdAsync(recurringPayment.InitialOrderId);
if (initialOrder is null)
{
recurringPayment.IsActive = false; // orphaned - quarantine
await _orderService.UpdateRecurringPaymentAsync(recurringPayment);
_logger.LogWarning("Recurring payment {Id} references deleted initial order {OrderId}",
recurringPayment.Id, recurringPayment.InitialOrderId);
return Array.Empty<string>();
}
return await _orderProcessingService.ProcessNextRecurringPaymentAsync(recurringPayment); Type guard
async Task<bool> InitialOrderExistsAsync(RecurringPayment rp)
=> await _orderService.GetOrderByIdAsync(rp.InitialOrderId) is not null; Try / catch
try
{
var errors = await _orderProcessingService.ProcessNextRecurringPaymentAsync(recurringPayment);
}
catch (NopException ex) when (ex.Message == "Initial order could not be loaded")
{
recurringPayment.IsActive = false;
await _orderService.UpdateRecurringPaymentAsync(recurringPayment);
_logger.LogCritical(ex, "Orphaned recurring payment {Id}", recurringPayment.Id);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Aggressive order cleanup scripts that delete orders but not related recurring payments; partial DB restore; buggy custom order-purge logic.
Related errors
- Customer could not be loaded
- Order cannot be loaded
- Shipping is required, but address is not available. Order ID
- Billing address is not available
- Shipping address is not available
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/f8863faaaa77870f.
Report an issue: GitHub.