nopSolutions/nopCommerce · error · Exception
This shipment is can't be marked as 'ready for pickup'. The
Error message
This shipment is can't be marked as 'ready for pickup'. The order has been placed without 'pickup in store' shipping option.
What it means
Thrown by ReadyForPickupAsync when order.PickupInStore is false. The order was placed for physical shipping, not store pickup, so marking it 'ready for pickup' is a domain violation - the correct action is Ship. Uses plain Exception. Note the message itself contains a grammatical typo ('is can't') present in the source.
Source
Thrown at src/Libraries/Nop.Services/Orders/OrderProcessingService.cs:2290
//check order status
await CheckOrderStatusAsync(order);
}
/// <summary>
/// Marks a shipment as ready for pickup
/// </summary>
/// <param name="shipment">Shipment</param>
/// <param name="notifyCustomer">True to notify customer</param>
/// <returns>A task that represents the asynchronous operation</returns>
public virtual async Task ReadyForPickupAsync(Shipment shipment, bool notifyCustomer)
{
ArgumentNullException.ThrowIfNull(shipment);
var order = await _orderService.GetOrderByIdAsync(shipment.OrderId) ?? throw new Exception("Order cannot be loaded");
if (!order.PickupInStore)
throw new Exception("This shipment is can't be marked as 'ready for pickup'. The order has been placed without 'pickup in store' shipping option.");
if (shipment.ReadyForPickupDateUtc.HasValue)
throw new Exception("This shipment is already marked as 'ready for pickup'");
shipment.ReadyForPickupDateUtc = DateTime.UtcNow;
await _shipmentService.UpdateShipmentAsync(shipment);
await AddOrderNoteAsync(order, $"Shipment# {shipment.Id} has been ready for pickup");
if (notifyCustomer)
{
var queuedEmailIds = await _workflowMessageService.SendShipmentReadyForPickupNotificationAsync(shipment, order.CustomerLanguageId);
if (queuedEmailIds.Any())
await AddOrderNoteAsync(order, $"\"Ready for pickup\" email (to customer) has been queued. Queued email identifiers: {string.Join(", ", queuedEmailIds)}.");
}
await _eventPublisher.PublishShipmentReadyForPickupAsync(shipment);
}
View on GitHub (pinned to 64bdf2ff08)
Solutions
- For non-pickup orders, call ShipAsync instead of ReadyForPickupAsync.
- Branch the fulfilment action on order.PickupInStore.
- Hide/disable the ReadyForPickup button for normal shipped orders.
Example fix
// before
await _orderProcessingService.ReadyForPickupAsync(shipment, notify);
// after
if (order.PickupInStore)
await _orderProcessingService.ReadyForPickupAsync(shipment, notify);
else
await _orderProcessingService.ShipAsync(shipment, notify); Defensive patterns
Strategy: validation
Validate before calling
var order = await _orderService.GetOrderByIdAsync(shipment.OrderId);
if (order is null)
return BadRequest("Order not found.");
if (!order.PickupInStore)
return BadRequest("Order is not pickup-in-store; use ShipAsync.");
await _orderProcessingService.ReadyForPickupAsync(shipment, notifyCustomer); Type guard
async Task<bool> IsPickupOrderAsync(Shipment shipment)
{
var order = await _orderService.GetOrderByIdAsync(shipment.OrderId);
return order is not null && order.PickupInStore;
} Try / catch
try
{
await _orderProcessingService.ReadyForPickupAsync(shipment, notifyCustomer);
}
catch (Exception ex) when (ex.Message.Contains("without 'pickup in store'"))
{
// route to the correct action
await _orderProcessingService.ShipAsync(shipment, notifyCustomer);
} Prevention
- Branch fulfilment actions on order.PickupInStore: ReadyForPickup for pickups, Ship for deliveries.
- In the admin UI, hide the ReadyForPickup control for normal shipped orders.
- Train operators on the distinction, or unify fulfilment behind a dispatcher that picks the right call.
When it happens
Trigger: Admin/operator or API calls ReadyForPickupAsync on a shipment whose order is a normal shipped order (PickupInStore == false). Typically operator using the wrong action, or a unified fulfilment endpoint calling ReadyForPickup unconditionally.
Common situations: Operator confusion between Ship and ReadyForPickup; custom integration routing all fulfilments through one method; mixed-mode orders handled by a single code path.
Related errors
- This shipment is can't be shipped. The order has been placed
- This shipment is already shipped
- Enter ready for pickup date
- Order cannot be loaded
- Enter shipped date
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/75c70717c9b8e7df.
Report an issue: GitHub.