Skip to content

fix(cart): fetch totals with all fields + fix inconsistent total calculation#16022

Open
shahednasser wants to merge 3 commits into
developfrom
fix/cart-totals-quantity
Open

fix(cart): fetch totals with all fields + fix inconsistent total calculation#16022
shahednasser wants to merge 3 commits into
developfrom
fix/cart-totals-quantity

Conversation

@shahednasser

@shahednasser shahednasser commented Jul 13, 2026

Copy link
Copy Markdown
Member

Note: this should be merged after #16021 to use the shared normalizeBigNumbers utility

Fix 1: Return totals when * fields are selected

Previously, we only returned totals when they're explicitely selected as the computation is expensive. However, this leads to unexpected results when a user passes * in the fields. So the following wouldn't work as expected:

// doesn't return totals
const { data: carts } = await query.graph({
    entity: "cart",
    fields: ["*"]
  })

// also doesn't return total. We strip all fields at the query layer when * is present
const { data: carts } = await query.graph({
    entity: "cart",
    fields: ["*", "total"]
  })

// this works
const { data: carts } = await query.graph({
    entity: "cart",
    fields: ["total", "id"]
  })

With the change in this PR, the totals will be returned as expected with *. This is fair as * by generally expensive and discouraged in the docs, and it matches the expectations of a user using it.

Caveat

All retrievals of * fields or not passing select to listOrders (and similar methods) will result in totals retrieval, since those will retrieve all order fields. Need to be documented and included as part of the next release notes. To avoid retrieving them, users must pass either an empty array (retrieving no fields), or specify specific fields to retrieve.

Fix 2: Total miscalculations based on retrieved items

In some use cases when a retrieving a specific field of cart's items without retrieving the quantity, the calculated totals are miscalculated. For example:

// totals are calculated
const { data: carts } = await query.graph({
    entity: "cart",
    fields: ["total", "items.quantity"]
  })

// totals are miscalculated as there's no quantity on the item
const { data: carts } = await query.graph({
    entity: "cart",
    fields: ["total", "items.unit_price"]
  })

This is unexpected behavior, the total shouldn't be impacted by which fields the user selects.

The solution in this PR has a caveat, which is that the quantity of items is now always returned when totals are returned even if not explicitely selected.

@shahednasser
shahednasser requested a review from a team as a code owner July 13, 2026 11:44
@changeset-bot

changeset-bot Bot commented Jul 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6be0021

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 80 packages
Name Type
@medusajs/cart Patch
@medusajs/medusa Patch
@medusajs/test-utils Patch
@medusajs/loyalty-plugin Patch
@medusajs/medusa-oas-cli Patch
integration-tests-http Patch
@medusajs/analytics Patch
@medusajs/api-key Patch
@medusajs/auth Patch
@medusajs/caching Patch
@medusajs/currency Patch
@medusajs/customer Patch
@medusajs/file Patch
@medusajs/fulfillment Patch
@medusajs/index Patch
@medusajs/inventory Patch
@medusajs/link-modules Patch
@medusajs/locking Patch
@medusajs/notification Patch
@medusajs/order Patch
@medusajs/payment Patch
@medusajs/pricing Patch
@medusajs/product Patch
@medusajs/promotion Patch
@medusajs/rbac Patch
@medusajs/region Patch
@medusajs/sales-channel Patch
@medusajs/settings Patch
@medusajs/stock-location Patch
@medusajs/store Patch
@medusajs/tax Patch
@medusajs/translation Patch
@medusajs/user Patch
@medusajs/workflow-engine-inmemory Patch
@medusajs/workflow-engine-redis Patch
@medusajs/draft-order Patch
@medusajs/oas-github-ci Patch
@medusajs/cache-inmemory Patch
@medusajs/cache-redis Patch
@medusajs/event-bus-local Patch
@medusajs/event-bus-redis Patch
@medusajs/analytics-local Patch
@medusajs/analytics-posthog Patch
@medusajs/auth-emailpass Patch
@medusajs/auth-github Patch
@medusajs/auth-google Patch
@medusajs/caching-redis Patch
@medusajs/file-local Patch
@medusajs/file-s3 Patch
@medusajs/fulfillment-manual Patch
@medusajs/locking-postgres Patch
@medusajs/locking-redis Patch
@medusajs/notification-local Patch
@medusajs/notification-sendgrid Patch
@medusajs/payment-stripe Patch
@medusajs/core-flows Patch
@medusajs/framework Patch
@medusajs/js-sdk Patch
@medusajs/modules-sdk Patch
@medusajs/orchestration Patch
@medusajs/query Patch
@medusajs/types Patch
@medusajs/utils Patch
@medusajs/workflows-sdk Patch
@medusajs/http-types-generator Patch
@medusajs/cli Patch
@medusajs/deps Patch
@medusajs/eslint-plugin Patch
@medusajs/telemetry Patch
@medusajs/admin-bundler Patch
@medusajs/admin-sdk Patch
@medusajs/admin-shared Patch
@medusajs/admin-vite-plugin Patch
@medusajs/dashboard Patch
@medusajs/icons Patch
@medusajs/toolbox Patch
@medusajs/ui-preset Patch
create-medusa-app Patch
medusa-dev-cli Patch
@medusajs/ui Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant