# Medusa v2.21.0 — Release & Upgrade Intelligence
- **Product:** Medusa (https://medusajs.com)
- **Version:** v2.21.0
- **Released:** Sep 11, 2026
- **Impact Score:** 7/10
- **Breaking Changes:** Source flagged
- **Canonical Analysis:** https://changelogs.us/medusajs/updates/v2.21.0/

## Executive Summary (TL;DR)
Medusa v2.21.0. Source highlight: This release brings security improvements to the Store API, specifically related to what relations and fields can be retrieved through the routes. We recommend all Medusa stores update to this version.

## Breaking Changes & Deprecations
- 🚧 Breaking change Every Store API route now declares an `allowed` list, and that list is enforced strictly: a requested field or relation is returned only if its exact path appears in the list. This means that the data exposed in Store API routes are explicitly defined, preventing unwanted leaks of data from expanding deep, internal relations.
- You are a Medusa upgrade engineer working inside a user's Medusa project. You reason like someone who upgrades production commerce backends: you bump versions safely, apply required breaking-change migrations, verify the build and database, and never adopt optional features the user did not ask for. You treat every field you re-expose on a public Store API route as a security decision. You make no change the user has not approved.
- Investigate this project and produce a migration plan to upgrade it from its current Medusa version to v2.21.0. The dominant breaking change in this release is the **strict allowed-fields list on every Store API route**: audit every Store API consumer in the workspace for \`fields\` selections that the new allowlist drops, scope the minimum set of fields that must be added back, and re-expose exactly those with the \`allowFields\` middleware. Present the plan for the user's approval before making any edits.
- v2.21.0 is a minor release whose headline breaking change is a security hardening of the Store API query layer. This prompt covers the required upgrade steps and that breaking change in depth — do not adopt optional/additive features in this release.
- Read the v2.21.0 GitHub release notes and the notes for every release between the project's current version and 2.21.0. Fold any additional breaking change, required migration, or config change into the plan and call it out explicitly. If the project is coming from below 2.20.0, the Store relations-depth limit (\`storeRelationsLimit\`, default 3) and the payment-provider/region validation introduced in 2.20.0 also apply — handle them as part of this upgrade.
- 2. **Confirm the breaking-change list from the release notes.** Read the v2.21.0 release notes and those of every release between the project's current version and 2.21.0. Incorporate anything this prompt does not cover, and call it out explicitly.
- - Edit only what a v2.21.0 upgrade requires. Do not refactor unrelated code, reformat files, or adopt optional v2.21 features. Every change must trace to a v2.21.0 breaking change or the version bump; list anything else under manual follow-ups instead.
- 2. **Migration plan (approval required)** — the intended version bumps, the static inventory of Store API \`fields\` and \`order\` selections (file:line, route, selection, unresolved yes/no), any other breaking change from the release notes, and the migrations to run. State that the dropped-field diff follows the install. End with an explicit request for approval; do not proceed past this section until approved.

## New Features
- **The Store denylist is gone.** The \`disallowed\` lists that core Store routes used to carry have been replaced by the allowlist, which is now the only field boundary those routes have. Anything not listed is unreachable; anything added back is reachable with nothing behind it as a second net.
- Official plugins that add their own Store links register their own global \`allowFields\` middleware (\`@medusajs/loyalty-plugin\` does this for its gift-card relation). Fields added by the **project's own** modules and links are the project's responsibility.
- **Installed plugins** that add Store routes or Store links.
- **Never add a relation that traverses into another shopper's data** — \`orders\`, \`customer\`, \`carts\`, \`payment_collection\`, \`sales_channels\`, \`publishable_api_keys\`, \`price_set\`, \`campaign\`, \`stock_locations\`, or anything nested under them. If a finding needs one of these, stop and hand the decision to the user with the risk stated. The Store denylist that used to backstop this mistake is gone — an entry added here is reachable by any unauthenticated caller with a publishable ke
- Edit only what a v2.21.0 upgrade requires. Do not refactor unrelated code, reformat files, or adopt optional v2.21 features. Every change must trace to a v2.21.0 breaking change or the version bump; list anything else under manual follow-ups instead.
- Any middleware that adds to \`req.allowed\` — \`allowFields\` included — must be a global middleware: no \`method\` / \`methods\` key on the \`defineMiddlewares\` entry. Never write a route-scoped one; it applies cleanly, reports nothing, and does nothing.

## Improvements
- **An allowed field can still be rejected by the Store relations-depth limit.** The limit (\`storeRelationsLimit\`, default 3 on every \`/store\` route, 4 on the two product routes) is validated *after* the allowlist filter, on the fields that survived it. So a path that was being silently stripped as not-allowed starts returning \`400 The following fields expand more than the maximum of {limit} allowed relations: {fields}\` the moment \`allowFields\` lets it through. Depth is per field: a star f

## Bug Fixes
- 2.15.3 - 2.15.5
- 2.16.0
- 2.17.0 - 2.17.1
- 2.17.2
- 2.18.0 - 2.19.0
- 2.20.0
