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

  1. For non-pickup orders, call ShipAsync instead of ReadyForPickupAsync.
  2. Branch the fulfilment action on order.PickupInStore.
  3. 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

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


AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13). Data as JSON: /api/errors/75c70717c9b8e7df. Report an issue: GitHub.