nopSolutions/nopCommerce · error · NopException
Selected shipping option is unavailable
Error message
Selected shipping option is unavailable
What it means
Thrown when a specific shipping option was selected by the customer (selectedOptionId is non-empty) but no available shipping option matches that name. This indicates the previously chosen option is no longer in the list of available options returned by the shipping providers.
Source
Thrown at src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs:675
if (details.Placement == ButtonPlacement.PaymentMethod && !isApplePay)
{
shipping.Type = details.IsPickup
? ShippingType.SHIPPING.ToString().ToUpper() //PICKUP_IN_STORE option doesn't work for some reason
: ShippingType.SHIPPING.ToString().ToUpper();
return shipping;
}
var (shippingOptions, pickupPoints) = await PrepareShippingOptionsAsync(details);
if (!shippingOptions?.Any() ?? true)
throw new NopException("No available shipping options");
var selectedShippingOption = shippingOptions.FirstOrDefault();
if (!string.IsNullOrEmpty(selectedOptionId))
{
var existingOption = shippingOptions
.FirstOrDefault(option => string.Equals(option.Name, selectedOptionId, StringComparison.InvariantCultureIgnoreCase))
?? throw new NopException("Selected shipping option is unavailable");
selectedShippingOption = existingOption;
}
if (selectedShippingOption is null)
throw new NopException("Selected shipping option is unavailable");
PickupPoint pickupPoint = null;
if (selectedShippingOption.IsPickupInStore)
{
pickupPoint = await pickupPoints.FirstOrDefaultAwaitAsync(async point =>
string.Equals(await GetShippingOptionNameAsync(new() { Name = point.Name, IsPickupInStore = true }), selectedShippingOption.Name) &&
string.Equals(point.ProviderSystemName, selectedShippingOption.ShippingRateComputationMethodSystemName));
details.IsPickup = true;
details.PickupPoint = pickupPoint;
//if the shipping option type is set to PICKUP, then the full name should start with S2S meaning ship to store (for example, S2S My Store)View on GitHub (pinned to 64bdf2ff08)
Solutions
- Clear the stored shipping selection and prompt the customer to re-select a shipping option
- Verify shipping rate computation methods are consistently returning the same option names across requests
- Check for time-sensitive or rate-limited shipping options that may expire during checkout
- Ensure no concurrent configuration changes to shipping methods during active checkout sessions
Example fix
// before
var existingOption = shippingOptions
.FirstOrDefault(option => string.Equals(option.Name, selectedOptionId, StringComparison.InvariantCultureIgnoreCase))
?? throw new NopException("Selected shipping option is unavailable");
// after
var existingOption = shippingOptions
.FirstOrDefault(option => string.Equals(option.Name, selectedOptionId, StringComparison.InvariantCultureIgnoreCase));
if (existingOption is null)
{
//fall back to the first available option instead of failing
existingOption = shippingOptions.FirstOrDefault();
await _logger.WarningAsync($"Selected shipping option '{selectedOptionId}' no longer available, falling back");
} Defensive patterns
Strategy: validation
Validate before calling
// Validate selected shipping option is still available
if (!string.IsNullOrEmpty(selectedOptionId))
{
var options = await _shippingService.GetShippingOptionsAsync(cart, address, "", storeId);
var exists = options.ShippingOptions.Any(o =>
string.Equals(o.Name, selectedOptionId, StringComparison.InvariantCultureIgnoreCase));
if (!exists)
selectedOptionId = null; // reset to force re-selection
} Try / catch
var (result, error) = await manager.PrepareShippingAsync(settings, details, selectedOptionId, isApplePay);
if (!string.IsNullOrEmpty(error) && error == "Selected shipping option is unavailable")
{
//reset selection and retry with first available option
var (retryResult, retryError) = await manager.PrepareShippingAsync(settings, details, null, isApplePay);
} Prevention
- Clear stale shipping selections when options change
- Validate the selected option name against current options on each request
- Handle session timeouts gracefully by re-prompting for shipping selection
When it happens
Trigger: PrepareShippingAsync receives a non-empty selectedOptionId; shippingOptions from PrepareShippingOptionsAsync contains options, but none have a Name matching selectedOptionId (case-insensitive comparison).
Common situations: The selected shipping method was deactivated or its rate expired between selection and payment; shipping provider rates changed between page loads; session-stored selection references a stale option name; shipping rate computation method returned different options due to configuration changes.
Related errors
- No available shipping options
- Exchange ratio not set for weight [{targetMeasureWeight.Name
- Shipping total couldn't be calculated
- Customer billing address not set
- Customer shipping address not set
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/68b55877832aa865.
Report an issue: GitHub.