nopSolutions/nopCommerce · error · Exception
Selected shipping method can't be loaded
Error message
Selected shipping method can't be loaded
What it means
Thrown by OpcSaveShippingMethod at line 1859 when the parsed shipping option name/systemName cannot be matched in the available shipping options list (cache via generic attribute, or freshly loaded via GetShippingOptionsAsync). The selected method does not exist for this cart/address/provider, so the Find returns null. Hardcoded literal message. The submitted selection is no longer valid.
Source
Thrown at src/Presentation/Nop.Web/Controllers/CheckoutController.cs:1859
//find it
//performance optimization. try cache first
var shippingOptions = await _genericAttributeService.GetAttributeAsync<List<ShippingOption>>(customer,
NopCustomerDefaults.OfferedShippingOptionsAttribute, store.Id);
if (shippingOptions == null || !shippingOptions.Any())
{
//not found? let's load them using shipping service
shippingOptions = (await _shippingService.GetShippingOptionsAsync(cart, await _customerService.GetCustomerShippingAddressAsync(customer),
customer, shippingRateComputationMethodSystemName, store.Id)).ShippingOptions.ToList();
}
else
{
//loaded cached results. let's filter result by a chosen shipping rate computation method
shippingOptions = shippingOptions.Where(so => so.ShippingRateComputationMethodSystemName.Equals(shippingRateComputationMethodSystemName, StringComparison.InvariantCultureIgnoreCase))
.ToList();
}
var shippingOption = shippingOptions.Find(so => !string.IsNullOrEmpty(so.Name) && so.Name.Equals(selectedName, StringComparison.InvariantCultureIgnoreCase))
?? throw new Exception("Selected shipping method can't be loaded");
//parse DesiredDeliveryDate
var desiredDeliveryDate = await ParseSelectedShippingMethodDeliveryDateAsync(shippingOption, shippingOptions, form);
if (desiredDeliveryDate != null)
await _genericAttributeService.SaveAttributeAsync(customer, NopCustomerDefaults.DesiredDeliveryDate, desiredDeliveryDate, store.Id);
//save
await _genericAttributeService.SaveAttributeAsync(customer, NopCustomerDefaults.SelectedShippingOptionAttribute, shippingOption, store.Id);
//load next step
return await OpcLoadStepAfterShippingMethod(cart);
}
catch (Exception exc)
{
await _logger.WarningAsync(exc.Message, exc, await _workContext.GetCurrentCustomerAsync());
return Json(new { error = 1, message = exc.Message });
}
}
View on GitHub (pinned to 64bdf2ff08)
Solutions
- Force a recompute of shipping options for the current cart/address before selection.
- Ensure the selected shippingRateComputationMethodSystemName matches an active, registered provider.
- Invalidate the cached OfferedShippingOptionsAttribute when address/cart changes.
- Render the option list from the same GetShippingOptionsAsync source used server-side.
Example fix
// before: posting a cached option whose provider is gone
$.post('OpcSaveShippingMethod', { shippingoption: 'Ground___Shipping.NowRemoved' });
// after: recompute and only send an offered option
const options = await fetchShippingOptions(cart, address); // server-side source
const pick = options[0];
$.post('OpcSaveShippingMethod', { shippingoption: `${pick.Name}___${pick.ShippingRateComputationMethodSystemName}` }); Defensive patterns
Strategy: validation
Validate before calling
// Recompute offered options for the current cart/address and only send one of them.
var offered = await _genericAttributeService
.GetAttributeAsync<List<ShippingOption>>(customer, NopCustomerDefaults.OfferedShippingOptionsAttribute, store.Id);
if (offered == null || !offered.Any())
offered = (await _shippingService.GetShippingOptionsAsync(cart, shipAddress, customer, systemName, store.Id)).ShippingOptions.ToList();
var match = offered.Find(o => o.Name == selectedName);
if (match == null) { /* re-render options, abort submit */ } Type guard
function isOfferedShippingOption(value /*: string*/, offered /*: {Name:string;ShippingRateComputationMethodSystemName:string}[]*/) {
const [name, sys] = value.split('___');
return offered.some(o => o.Name === name && o.ShippingRateComputationMethodSystemName === sys);
} Try / catch
if (data.error && /shipping method can't be loaded/i.test(data.message)) {
await invalidateOfferedShippingCache();
await reloadShippingOptions();
} Prevention
- Invalidate OfferedShippingOptionsAttribute when address/cart changes.
- Render the option list from the same GetShippingOptionsAsync source as the server.
- Confirm the provider systemName matches an active shipping rate computation method.
When it happens
Trigger: Client posts a valid 'Name___SystemName' but no matching ShippingOption exists: provider disabled, options not computed for the current address/cart, cache (OfferedShippingOptionsAttribute) stale, or the systemName doesn't match any active shipping rate computation method.
Common situations: Shipping provider disabled/removed after options were cached; address changed so options differ; cart contents changed so rates differ; provider plugin uninstalled; cached OfferedShippingOptions attribute from a previous address.
Related errors
- One page checkout is disabled
- Anonymous checkout is not allowed
- Shipping is not required
- Selected shipping method can't be parsed
- Checkout.Address.NotFound
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/5a2acdcd241542eb.
Report an issue: GitHub.