GoogleCloudPlatform/microservices-demo · error
could not retrieve product #%s
Error message
could not retrieve product #%s
What it means
While building the cart item views, viewCartHandler failed to fetch one of the products in the cart from productcatalogservice (fe.getProduct). The error uses errors.Wrapf with the product ID and is rendered as HTTP 500, aborting the whole cart page.
Source
Thrown at src/frontend/handlers.go:287
}
shippingCost, err := fe.getShippingQuote(r.Context(), cart, currentCurrency(r))
if err != nil {
renderHTTPError(log, r, w, errors.Wrap(err, "failed to get shipping quote"), http.StatusInternalServerError)
return
}
type cartItemView struct {
Item *pb.Product
Quantity int32
Price *pb.Money
}
items := make([]cartItemView, len(cart))
totalPrice := pb.Money{CurrencyCode: currentCurrency(r)}
for i, item := range cart {
p, err := fe.getProduct(r.Context(), item.GetProductId())
if err != nil {
renderHTTPError(log, r, w, errors.Wrapf(err, "could not retrieve product #%s", item.GetProductId()), http.StatusInternalServerError)
return
}
price, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))
if err != nil {
renderHTTPError(log, r, w, errors.Wrapf(err, "could not convert currency for product #%s", item.GetProductId()), http.StatusInternalServerError)
return
}
multPrice := money.MultiplySlow(*price, uint32(item.GetQuantity()))
items[i] = cartItemView{
Item: p,
Quantity: item.GetQuantity(),
Price: &multPrice}
totalPrice = money.Must(money.Sum(totalPrice, multPrice))
}
totalPrice = money.Must(money.Sum(totalPrice, *shippingCost))
year := time.Now().Year()
View on GitHub (pinned to 72ba613a05)
Solutions
- Remove the offending product ID from the user's cart or purge stale cart entries.
- Check productcatalogservice availability and its data file.
- Verify PRODUCT_CATALOG_SERVICE_ADDR configuration.
- Skip missing products gracefully (warn + exclude item) instead of failing the entire cart page.
Example fix
// before
p, err := fe.getProduct(r.Context(), item.GetProductId())
if err != nil {
renderHTTPError(log, r, w, errors.Wrapf(err, "could not retrieve product #%s", item.GetProductId()), http.StatusInternalServerError)
// after
p, err := fe.getProduct(r.Context(), item.GetProductId())
if err != nil {
log.WithField("product", item.GetProductId()).Warn("product missing from catalog, skipping cart item")
continue // or remove item from cart via fe.insertCart(..., 0) Defensive patterns
Strategy: fallback
Validate before calling
// check cart entries reference live catalog IDs before rendering
for _, item := range cart {
if item.GetProductId() == "" {
log.Warn("cart item missing product id")
}
} Try / catch
p, err := fe.getProduct(r.Context(), item.GetProductId())
if err != nil {
log.WithField("product", item.GetProductId()).Warn("missing product; skipping cart item")
continue
} Prevention
- Purge cart items whose products no longer exist in the catalog.
- Skip/omit missing products instead of returning HTTP 500 for the page.
- Keep catalog data stable across deploys or version product IDs.
- Monitor catalog lookups failing with NotFound from cart views.
When it happens
Trigger: GET /cart when any product_id stored in the cart no longer resolves via productcatalogservice (item removed from catalog) or the catalog RPC fails.
Common situations: cart contains a stale product ID after a catalog update/redeploy of productcatalogservice data, catalog service outage, PRODUCT_CATALOG_SERVICE_ADDR misconfigured.
Related errors
- failed to add to cart
- failed to empty cart
- could not convert currency for product #%s
- failed to get user cart during checkout: %+v
- failed to empty user cart during checkout: %+v
AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02).
Data as JSON: /api/errors/f924ed9e3e6ebb42.
Report an issue: GitHub.