dotnet/eShop · error · CatalogDomainException

Item units desired should be greater than zero

Error message

Item units desired should be greater than zero

What it means

Thrown by CatalogItem.RemoveStock when the supplied quantityDesired is less than or equal to zero. RemoveStock validates its input as a precondition because a non-positive decrement is a programming/contract error, not a legitimate inventory operation. It is a CatalogDomainException.

Source

Thrown at src/Catalog.API/Model/CatalogItem.cs:71

    /// 
    /// If there is sufficient stock of an item, then the integer returned at the end of this call should be the same as quantityDesired. 
    /// In the event that there is not sufficient stock available, the method will remove whatever stock is available and return that quantity to the client.
    /// In this case, it is the responsibility of the client to determine if the amount that is returned is the same as quantityDesired.
    /// It is invalid to pass in a negative number. 
    /// </summary>
    /// <param name="quantityDesired"></param>
    /// <returns>int: Returns the number actually removed from stock. </returns>
    /// 
    public int RemoveStock(int quantityDesired)
    {
        if (AvailableStock == 0)
        {
            throw new CatalogDomainException($"Empty stock, product item {Name} is sold out");
        }

        if (quantityDesired <= 0)
        {
            throw new CatalogDomainException($"Item units desired should be greater than zero");
        }

        int removed = Math.Min(quantityDesired, this.AvailableStock);

        this.AvailableStock -= removed;

        return removed;
    }

    /// <summary>
    /// Increments the quantity of a particular item in inventory.
    /// <param name="quantity"></param>
    /// <returns>int: Returns the quantity that has been added to stock</returns>
    /// </summary>
    public int AddStock(int quantity)
    {
        int original = this.AvailableStock;

View on GitHub (pinned to 9b4f9434f4)

Solutions

  1. Validate quantityDesired > 0 at the calling boundary (controller/handler) and reject the request with a 400 before it reaches the domain.
  2. Trace where the quantity originates and ensure it is sourced from a positive Units value on the order line, never an unset default.
  3. If the intent is to probe availability, read AvailableStock directly instead of calling RemoveStock with 0.
  4. Add a guard clause / FluentValidation rule: RuleFor(x => x.Quantity).GreaterThan(0).

Example fix

// before
var taken = item.RemoveStock(line.Units); // line.Units may be 0

// after
if (line.Units <= 0) throw new ArgumentException("Quantity must be positive", nameof(line.Units));
var taken = item.RemoveStock(line.Units);
Defensive patterns

Strategy: validation

Validate before calling

if (qty <= 0) throw new ArgumentOutOfRangeException(nameof(qty));
var taken = item.RemoveStock(qty);

Type guard

static bool IsValidQuantity(int qty) => qty > 0;

Try / catch

try {
    item.RemoveStock(qty);
} catch (CatalogDomainException ex) when (ex.Message.Contains("greater than zero")) {
    // programming/contract error — log and reject the request as 400
}

Prevention

When it happens

Trigger: A caller computes the desired quantity from a cart/order line and passes 0 or a negative value — e.g. an order item with Units <= 0, a default-int field that was never set, or arithmetic that underflowed. Also seen when an upstream mapping sends an empty/zero quantity.

Common situations: DTO mapping that drops an unset Quantity field to 0; client sending a request with no quantity; unit test invoking RemoveStock(0) as a no-op probe; subtraction producing a negative remainder passed straight through.

Related errors


AI-assisted analysis of dotnet/eShop@9b4f9434f4 (2026-08-13). Data as JSON: /api/errors/f230aff394f61637. Report an issue: GitHub.