# medusa changelog > medusa release notes. - Vendor: medusa - Category: Frameworks & Libraries - Official site: https://github.com/medusajs/medusa#readme - Tracked by: What's New (https://whatsnew.fyi/product/medusa) - Harvested from: GitHub (medusajs/medusa) - Entries below: 10 (newest first) What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. ## Releases ### v2.18.0 - Date: 2026-07-23 - Version: v2.18.0 - Original notes: https://github.com/medusajs/medusa/releases/tag/v2.18.0 - Permalink: https://whatsnew.fyi/product/medusa/releases/v2.18.0 ##### Highlights This release comes with new features, bug fixes, and dependency updates for better security. Medusa MCP users can update their project using the following prompt: ```bash Update my Medusa project to v2.18.0 ``` ###### Balanced Query Load Strategy by Default 🚧 Breaking change The default database load strategy has changed from `SELECT_IN` to `BALANCED`, matching MikroORM v7's intended default. MikroORM picks between a joined and a select-in approach per relation, which improves query performance in most cases. Because it changes how relations are loaded, review query-heavy paths and any snapshot or query-count assertions in your tests after upgrading. --- ###### Return Value of Generated Internal Service's delete Method Changed 🚧 Breaking change > This affects usages of [generated internal services](https://docs.medusajs.com/learn/fundamentals/modules/service-factory#generated-internal-services). They do not impact methods generated by `MedusaService` such as `deletePosts`. The return value of the `delete` method of a generated internal service has been changed to cater for composite primary keys: ```ts // before delete(idOrSelector: string, sharedContext?: Context): Promise delete(idOrSelector: string[], sharedContext?: Context): Promise delete(idOrSelector: object, sharedContext?: Context): Promise delete(idOrSelector: object[], sharedContext?: Context): Promise delete( idOrSelector: { selector: FilterQuery | BaseFilterable> }, sharedContext?: Context ): Promise // after delete( idOrSelector: string, sharedContext?: Context ): Promise[]> delete( idOrSelector: string[], sharedContext?: Context ): Promise[]> delete( idOrSelector: object, sharedContext?: Context ): Promise[]> delete( idOrSelector: object[], sharedContext?: Context ): Promise[]> delete( idOrSelector: { selector: FilterQuery | BaseFilterable> }, sharedContext?: Context ): Promise[]> ``` The method now either returns an array of deleted IDs if the primary key is an `id` field, or an array of objects, each object's keys are the composite primary key's name, and value is the primary key's value. For example, `[{ foo: "foo-1", var: "bar-1" }]`. If you use generated internal services in your module, make sure to update their usages to handle the new return value. For example: ```ts // before const deletedIds = await postService.delete(idsOrObject) // type was string // after // type could be an array of string IDs or objects. const deletedData = await postService.delete(idsOrObject) const isStringIds = deletedData.some((data) => typeof data === "string") ``` --- ###### Improved Configurable Data Tables in the Admin Dashboard The view configurations feature in the Medusa Admin dashboard. has been improved Users can resize columns, control column visibility and ordering, and save view configurations, with dynamic filter and sort resolution, custom cell renderer registration, and a UI for managing property labels. Learn more in [this documentation](https://docs.medusajs.com/resources/commerce-modules/settings/configure-view-configurations) https://github.com/user-attachments/assets/995cdb60-f9d7-4f1b-9ce9-3b24671130fb --- ###### Transfer an Order to a Guest Customer Orders can now be transferred to a guest customer from the admin dashboard without going through a full order transfer flow. This makes it possible to reassign an order to a guest account when it was placed under the wrong customer or needs to be detached from a registered account. The original customer transfer flow remains for transferring orders to registered customers. [#15926](https: _[Truncated at 4000 characters β€” full notes: https://github.com/medusajs/medusa/releases/tag/v2.18.0]_ ### v2.17.2 - Date: 2026-07-01 - Version: v2.17.2 - Original notes: https://github.com/medusajs/medusa/releases/tag/v2.17.2 - Permalink: https://whatsnew.fyi/product/medusa/releases/v2.17.2 ##### Highlights ###### before / after on widgets injection zones 🚧 Breaking change Since the components in a `LayoutComposer` controlled page are now arranged through the Editor view (including widgets), the `.after | .before` widget injection zones don't have an effect on where the Widget is placed within its injection zone - you should configure this, just like with any other layout component, through the Editor view. The `.side` is still relevant for Two Column page layouts. ###### New Admin Layout Composer The admin dashboard layout is now fully customizable through a reworked Layout Composer. You can rearrange the Topbar, Sidebar, Settings Sidebar and pages with drag and drop, and your arrangement is persisted in the database so it stays consistent across sessions and users. This rework started as a community contribution from [@leobenzol](https://github.com/leobenzol), who built the drag-and-drop Layout Composer and settings persistence and applied it across the shell. Thanks to their work, extending and reordering the dashboard layout is now a first-class part of the admin. A prime example of the kind of high-value features the community can drive in Medusa. Read more in the [announcement](https://medusajs.com/blog/announcing-layout-composer/). [#15721](https://github.com/medusajs/medusa/pull/15721) [#15861](https://github.com/medusajs/medusa/pull/15861) [#15862](https://github.com/medusajs/medusa/pull/15862) --- ###### Async Payment Methods Support Medusa now supports asynchronous payment methods, where a payment is confirmed after the initial request through provider webhooks rather than synchronously. The support spans the Payment module, the Stripe provider, core workflows, the JS SDK, and the admin dashboard, so async methods are handled consistently across the checkout and payment lifecycle. [#15085](https://github.com/medusajs/medusa/pull/15085) --- ###### Tiered Pricing for Price List Prices Price list prices now support quantity-based tiers directly in the admin. Click a price cell in the price list edit form to define multiple price tiers per variant and currency, making it straightforward to set up bulk discounts and other quantity-based pricing strategies across regions and currencies. https://github.com/user-attachments/assets/1521c033-aee9-4fca-a2b8-d09ea2a95e2e [#15258](https://github.com/medusajs/medusa/pull/15258) --- ###### Contextual Browser Tab Titles The admin dashboard now sets a descriptive document title for each page, so multiple open tabs are easy to tell apart. List pages show the section name (for example "Products - Medusa") and detail pages surface the entity name (for example a product's title or an order's display id). Titles are resolved through a new `seo` resolver on each route's handle. Custom admin pages in your own project can set their tab title the same way, by exporting a `handle` with an `seo` resolver from the route file. Return a static title, or derive one from the route's loader data via `match.data`: ```tsx // src/admin/routes/custom/page.tsx import { defineRouteConfig } from "@medusajs/admin-sdk" export const handle = { seo: () => ({ title: "My Custom Page" }), } export const config = defineRouteConfig({ label: "My Custom Page", }) const CustomPage = () => { return
My custom page
} export default CustomPage ``` [#14426](https://github.com/medusajs/medusa/pull/14426) ##### Features - feat: drag&drop LayoutComposer, settings db persistence by [@leobenzol](https://github.com/leobenzol) in [#15721](https://github.com/medusajs/medusa/pull/15721) - feat(payment,payment-stripe,core-flows,medusa,dashboard,js-sdk,utils,types): introduce async payment methods support by [@NicolasGorga](https://github.com/NicolasGorga) in [#15085](https://github.com/medusajs/medusa/pull/15085) - feat(dashboard): add dynamic document titles for browser tabs by [@bqst](https://github.com/ _[Truncated at 4000 characters β€” full notes: https://github.com/medusajs/medusa/releases/tag/v2.17.2]_ ### v2.17.1 - Date: 2026-06-25 - Version: v2.17.1 - Original notes: https://github.com/medusajs/medusa/releases/tag/v2.17.1 - Permalink: https://whatsnew.fyi/product/medusa/releases/v2.17.1 ##### Highlights ###### Regression with workers in Redis Event Bus This release fixes a critical bug introduced in 2.17.0. **What** Not await `bullWorker_.run()` in event-bus-redis `onApplicationStart` **Why** `bullWorker_.run()` is designed to return only when the worker is closed (https://github.com/taskforcesh/bullmq/issues/2128). This bug had flown under the radar until we started awaiting all modules `onApplicationStart` [here](https://github.com/medusajs/medusa/pull/15786). The effect is that when running in worker mode, application startup hangs indefinitely. It does not happen in server mode because `bullWorker_` only exists in worker mode. ##### Bugs * fix: fix event-bus-redis onApplicationStart hook by [@peterlgh7](https://github.com/peterlgh7) in [#15838](https://github.com/medusajs/medusa/pull/15838) * fix: properly handle undefined bullWorker by [@peterlgh7](https://github.com/peterlgh7) in [#15842](https://github.com/medusajs/medusa/pull/15842) ##### Other Changes * i18n(ja): complete dashboard translations β€” fill 511 missing keys by [@greymoth-jp](https://github.com/greymoth-jp) in [#15839](https://github.com/medusajs/medusa/pull/15839) ##### New Contributors * @greymoth-jp made their first contribution in [#15839](https://github.com/medusajs/medusa/pull/15839) **Full Changelog**: [v2.17.0...v2.17.1](https://github.com/medusajs/medusa/compare/v2.17.0...v2.17.1) ### v2.17.0 - Date: 2026-06-24 - Version: v2.17.0 - Original notes: https://github.com/medusajs/medusa/releases/tag/v2.17.0 - Permalink: https://whatsnew.fyi/product/medusa/releases/v2.17.0 ##### Highlights > **IMPORTANT:** This release contains a regression around worker instances. You should not upgrade to this but instead 2.17.1. ###### Global Product Options 🚧 Breaking change Product options in Medusa can now be global β€” defined once at the store level and reusable across any number of products. Previously, options such as "Size" or "Color" had to be recreated independently for each product. With this release, you define an option once, attach it to as many products as you need, and manage values from a single place. This unlocks consistent variant modeling across large catalogs and reduces duplication when building storefront filters or admin tooling. [#13817](https://github.com/medusajs/medusa/pull/13817) Read more in the [announcement post](https://medusajs.com/blog/announcing-global-product-options/). --- ###### Provider-Agnostic Auth Verification 🚧 Breaking change Auth verification (email, phone, etc.) has been reworked into a flexible, provider-based system. You can now declare exactly which verifications are required per actor type and auth provider via the new `authVerificationsPerActor` config β€” for example, require email verification for customers using `emailpass`, but skip it for those signing in with Google. Codes are issued and confirmed through pluggable code providers, with a built-in token provider out of the box. This is a breaking change: - The verification endpoints moved from `POST /auth/:actor_type/:auth_provider/verification/request` (and `/confirm`) to flat `POST /auth/verification/request` and `POST /auth/verification/confirm`. The request route is now authenticated and takes `entity_id`, `entity_type`, and `code_provider` in the body instead of actor/provider in the URL. - The JS SDK's auth verification methods were updated to match β€” upgrade the SDK and adjust any custom verification calls. - A database migration replaces the `auth_verification_token` table with a new `auth_verification` table. Run `npx medusa db:migrate` after upgrading; any pending (unconfirmed) verifications are discarded. [#15696](https://github.com/medusajs/medusa/pull/15696) --- ###### Medusa ESLint Plugin A new `@medusajs/eslint-plugin` package ships with this release, bringing first-party linting rules for Medusa projects. The plugin covers API routes, subscribers, scheduled jobs, admin customizations, and module patterns. Lint runs automatically via the Medusa CLI when the plugin is installed: ```bash npx medusa lint ``` Rules are grouped into config presets (`recommended`, `modules`, etc.) so you can opt in to the level of strictness that fits your project. [#15719](https://github.com/medusajs/medusa/pull/15719) [#15697](https://github.com/medusajs/medusa/pull/15697) [#15700](https://github.com/medusajs/medusa/pull/15700) [#15714](https://github.com/medusajs/medusa/pull/15714) [#15715](https://github.com/medusajs/medusa/pull/15715) [#15717](https://github.com/medusajs/medusa/pull/15717) ##### Features * feat: global product options by [@willbouch](https://github.com/willbouch) in [#13817](https://github.com/medusajs/medusa/pull/13817) * feat(order,types): add line_item_metadata to order responses by [@NicolasGorga](https://github.com/NicolasGorga) in [#15727](https://github.com/medusajs/medusa/pull/15727) * feat(dashboard): allow already registered actor to accept admin invite by [@NicolasGorga](https://github.com/NicolasGorga) in [#15791](https://github.com/medusajs/medusa/pull/15791) * feat(file-s3): add acl option to disable ACL headers on uploads by [@mrpackethead](https://github.com/mrpackethead) in [#15764](https://github.com/medusajs/medusa/pull/15764) * feat: Revamp auth verification setup by [@sradevski](https://github.com/sradevski) in [#15696](https://github.com/medusajs/medusa/pull/15696) * feat(admin-shared,dashboard,draft-order,loyalty): LayoutComposer, injection zones for plugins by [@leobenzol](https: _[Truncated at 4000 characters β€” full notes: https://github.com/medusajs/medusa/releases/tag/v2.17.0]_ ### v2.16.0 - Date: 2026-06-18 - Version: v2.16.0 - Original notes: https://github.com/medusajs/medusa/releases/tag/v2.16.0 - Permalink: https://whatsnew.fyi/product/medusa/releases/v2.16.0 ##### Highlights This release comes with many improvements and bug fixes. We highly recommend updating to leverage these changes in your application. For the Medusa MCP users, you can ask your AI agent to update your project with the following prompt: ```bash update my Medusa project to v2.16.0 ``` It will fetch the necessary changes needed to update your project.
Update Prompt for AI Agents ~~~text You are a Medusa upgrade specialist. You work inside a user's Medusa application β€” a Medusa backend project and, when present, its companion storefront. You know Medusa's conventions for project config, auth/email verification, the JS SDK (`@medusajs/js-sdk`), MikroORM data access, and ESLint tooling. 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.16.0, then present the plan for the user's approval before making any edits. v2.16.0 is a minor release with several breaking changes that require code or config updates. This prompt covers only the required upgrade steps and breaking changes β€” additive features in this release (tax line context hook, multi-shipping-method carts, new/custom admin injection zones) are intentionally out of scope; do not implement them. The breaking changes in scope: 1. **Package version bump to v2.16.0** for all `@medusajs/*` packages. 2. **MikroORM bumped to 6.6.14** (security fix for CVE-2026-44680). `manager.find` now throws on relations that don't exist on an entity instead of silently ignoring them. 3. **`react-router-dom` bumped to `6.30.4`** (defensive security update). Admin customizations may break if not updated. 4. **ESLint plugin** (`@medusajs/eslint-plugin`). New projects ship with it; existing projects should add it. Once configured, `medusa build` and `medusa develop` run linting by default. 5. **Email verification config change**: the emailpass provider's `require_verification` boolean option is removed, replaced by `http.authVerificationsPerActor`. 6. **Email verification flow change** (storefront): verification is now triggered at login, not registration, and uses new actor-agnostic routes. 7. **Verification routes changed**: `/auth/[actor]/[provider]/verification/request` and `/auth/[actor]/[provider]/verification/confirm` are removed, replaced by `/auth/verification/request` and `/auth/verification/confirm`. 8. **JS SDK email-verification signature changes** for `auth.register`, `auth.login`, `auth.verification.request`, and `auth.verification.confirm`. 9. **Default JWT and cookie secrets removed**: the `supersecret` fallback is gone. In production, the app throws and fails to start if `http.jwtSecret` / `http.cookieSecret` are not set. For anything not covered here, consult the official Medusa documentation at https://docs.medusajs.com or the Medusa MCP server before acting. Do not guess at APIs, config keys, or route shapes β€” verify them. You are given access to the project's working directory. You must discover the following yourself; do not assume: - **Project shape**: standalone Medusa project vs. monorepo (e.g. `apps/backend` + workspaces). Check for a root `package.json` with workspaces and an `apps/` directory. - **Storefront presence**: a separate storefront app/repo or directory that uses `@medusajs/js-sdk`. If no storefront is in this workspace, treat storefront steps as guidance to surface to the user, not edits you can make. - **Current Medusa version**: read from `package.json` dependencies. - **Whether the project uses email verification**: search for `require_verification`, `authVerificationsPerActor`, `/auth/*/verification/`, `sdk.auth.verification`, or `verification_required`. - **Whether secrets are configured**: inspect `medusa-config.ts`/`.js` for `http.jwtSecret` / `http.cookieSecret` and the environment for `JWT_SEC _[Truncated at 4000 characters β€” full notes: https://github.com/medusajs/medusa/releases/tag/v2.16.0]_ ### v2.15.5 - Date: 2026-06-01 - Version: v2.15.5 - Original notes: https://github.com/medusajs/medusa/releases/tag/v2.15.5 - Permalink: https://whatsnew.fyi/product/medusa/releases/v2.15.5 ##### Highlights ###### Multi-Factor Authentication Medusa now supports multi-factor authentication (MFA). The admin dashboard includes a complete MFA UI that allows users to set up and manage their authentication methods. MFA lifecycle events are now emitted for tracking authentication flows. After updating, make sure to set the `AUTH_MFA_ENCRYPTION_KEY` environment variable to a random 64-character string: ```bash AUTH_MFA_ENCRYPTION_KEY=your_random_64_character_string ``` Also, if you've added the Auth Module to your `medusa-config.ts` file to set any of its options, make sure to set the `mfa.encryption_key` option to the same environment variable: ```ts title="medusa-config.ts" import { Modules, ContainerRegistrationKeys } from "@medusajs/framework/utils" // ... module.exports = defineConfig({ // ... modules: [ { resolve: "@medusajs/medusa/auth", dependencies: [Modules.CACHE, ContainerRegistrationKeys.LOGGER], options: { mfa: { encryption_key: process.env.AUTH_MFA_ENCRYPTION_KEY, }, // other options... }, }, ], }) ``` If you don't set the `mfa.encryption_key` option, you'll get a "MFA encryption key is required to use MFA methods" error whenever trying to enroll or verify an MFA factor. [#15496](https://github.com/medusajs/medusa/pull/15496) [#15493](https://github.com/medusajs/medusa/pull/15493) [#15495](https://github.com/medusajs/medusa/pull/15495) ##### Features * feat: add admin MFA UI by [@christiananese](https://github.com/christiananese) in [#15493](https://github.com/medusajs/medusa/pull/15493) * Emit MFA lifecycle events by [@christiananese](https://github.com/christiananese) in [#15495](https://github.com/medusajs/medusa/pull/15495) * Emailpass email verification primitives by [@christiananese](https://github.com/christiananese) in [#15496](https://github.com/medusajs/medusa/pull/15496) * feat(dashboard,framework,rbac,js-sdk,types,utils,medusa): rbac admin dashboard utils by [@fPolic](https://github.com/fPolic) in [#14593](https://github.com/medusajs/medusa/pull/14593) ##### Bugs * fix(core-flows): avoid refunding captures made in separate completeCartWorkflow executions by [@NicolasGorga](https://github.com/NicolasGorga) in [#15527](https://github.com/medusajs/medusa/pull/15527) * fix(utils): add mfa to inline snapshot test assertion by [@NicolasGorga](https://github.com/NicolasGorga) in [#15518](https://github.com/medusajs/medusa/pull/15518) * fix(core-flows): respect allow_backorder when calculating pickup inventory availability by [@marlinjai](https://github.com/marlinjai) in [#15440](https://github.com/medusajs/medusa/pull/15440) * Allow cancelling pending MFA setup by [@christiananese](https://github.com/christiananese) in [#15475](https://github.com/medusajs/medusa/pull/15475) * fix(dashboard): order list status badges show correct colors when view_configurations is enabled by [@shiminshen](https://github.com/shiminshen) in [#15430](https://github.com/medusajs/medusa/pull/15430) * fix(core-flows): use hasPermission util to perform checks in validateUserRolePermissionsStep by [@NicolasGorga](https://github.com/NicolasGorga) in [#15470](https://github.com/medusajs/medusa/pull/15470) * fix(core-flows,medusa): align validate user permissions check with hasPermission util by [@NicolasGorga](https://github.com/NicolasGorga) in [#15465](https://github.com/medusajs/medusa/pull/15465) ##### Documentation * docs: update cloudflare config by [@shahednasser](https://github.com/shahednasser) in [#15499](https://github.com/medusajs/medusa/pull/15499) * docs: migrate main docs to cloudflare by [@shahednasser](https://github.com/shahednasser) in [#15498](https://github.com/medusajs/medusa/pull/15498) * docs: add TSDocs for "rbac admin dashboard utils (#14593)" by [@shahednasser](https://github.com/shahednasser) in [#15476](https://github.com/m _[Truncated at 4000 characters β€” full notes: https://github.com/medusajs/medusa/releases/tag/v2.15.5]_ ### v2.15.3 - Date: 2026-05-21 - Version: v2.15.3 - Original notes: https://github.com/medusajs/medusa/releases/tag/v2.15.3 - Permalink: https://whatsnew.fyi/product/medusa/releases/v2.15.3 ##### Highlights ###### Multi-Factor Authentication Support This release adds the primitives to support Multi-Factor Authentication (MFA) for enhanced security. This includes new authentication provider primitives, API routes for MFA management, and retrieval functionality. The implementation provides a foundation for integrating various MFA methods. --- ###### Promotion Code Visibility Improvements When promotion codes are skipped due to budget or usage limits, the system now surfaces this information to provide better visibility into why certain promotions weren't applied. This helps merchants understand promotion application behavior and troubleshoot issues. [#15396](https://github.com/medusajs/medusa/pull/15396) ##### Features * feat(js-sdk): add MFA auth helpers by [@christiananese](https://github.com/christiananese) in [#15441](https://github.com/medusajs/medusa/pull/15441) * feat(ui): add CodeInput component by [@christiananese](https://github.com/christiananese) in [#15424](https://github.com/medusajs/medusa/pull/15424) ##### Bugs * fix(design-system): broaden React peer dependencies to support v18 an… by [@Suh0161](https://github.com/Suh0161) in [#15271](https://github.com/medusajs/medusa/pull/15271) * fix(core-flows): harden create payment sessions when customer has no account holders by [@Suh0161](https://github.com/Suh0161) in [#15264](https://github.com/medusajs/medusa/pull/15264) * fix(dashboard): include inventory query in detail key by [@Derekko-web](https://github.com/Derekko-web) in [#15417](https://github.com/medusajs/medusa/pull/15417) * fix(dashboard): complete and correct Thai (th) translations by [@Ligament](https://github.com/Ligament) in [#15409](https://github.com/medusajs/medusa/pull/15409) * fix(test-utils, link-modules): encode URL credentials and fix schema-qualified RENAME TO by [@Ultron03](https://github.com/Ultron03) in [#15344](https://github.com/medusajs/medusa/pull/15344) * fix(medusa): fix filtering by categories and tags in /store/products with the index module by [@shahednasser](https://github.com/shahednasser) in [#15405](https://github.com/medusajs/medusa/pull/15405) * fix(create-medusa-app): fix incorrect command replacement when using yarn and npm by [@shahednasser](https://github.com/shahednasser) in [#15436](https://github.com/medusajs/medusa/pull/15436) * fix(utils): implement tokenized free text search by [@Suh0161](https://github.com/Suh0161) in [#15275](https://github.com/medusajs/medusa/pull/15275) * fix(core-flows): fix incorrect stock location picked for item with backorder in a sales channel with multiple locations by [@shahednasser](https://github.com/shahednasser) in [#15159](https://github.com/medusajs/medusa/pull/15159) ##### Documentation * docs: configure posthog capturing by [@shahednasser](https://github.com/shahednasser) in [#15449](https://github.com/medusajs/medusa/pull/15449) * docs: fix information about preview environments by [@shahednasser](https://github.com/shahednasser) in [#15445](https://github.com/medusajs/medusa/pull/15445) * docs: fix documentation issues in triage inbox by [@shahednasser](https://github.com/shahednasser) in [#15427](https://github.com/medusajs/medusa/pull/15427) * docs: revert Cloudflare migration by [@shahednasser](https://github.com/shahednasser) in [#15438](https://github.com/medusajs/medusa/pull/15438) * docs: add logging by [@shahednasser](https://github.com/shahednasser) in [#15435](https://github.com/medusajs/medusa/pull/15435) * docs: prepare to deploy to medusa cloud by [@shahednasser](https://github.com/shahednasser) in [#15429](https://github.com/medusajs/medusa/pull/15429) * docs: track logged in users by [@shahednasser](https://github.com/shahednasser) in [#15425](https://github.com/medusajs/medusa/pull/15425) * docs: added cloud docs for backups by [@shahednasser](https://github.com/shahednasser) in [#15408](https://github.com/medu _[Truncated at 4000 characters β€” full notes: https://github.com/medusajs/medusa/releases/tag/v2.15.3]_ ### v2.15.2 - Date: 2026-05-13 - Version: v2.15.2 - Original notes: https://github.com/medusajs/medusa/releases/tag/v2.15.2 - Permalink: https://whatsnew.fyi/product/medusa/releases/v2.15.2 ##### Highlights ###### Fix Migrations Regressions Following the MikroORM update in v2.13.6, a regression was introduced where running `medusa db:migrate` generated a full database snapshot for custom modules. Then, when running `medusa db:generate` later, a bug in the migration generation caused the module snapshot to be overridden by the database snapshot, which would then generate migrations dropping all the tables in the database. We encourage all users on a version after v2.13.6 to update to this release to mitigate database issues. After updating, please inspect the `migrations/.snapshot.**.json` files in your custom modules and: - Delete any snapshots with the name `.snapshot-.json`. - For module snapshots (`.snapshot-.json`), confirm that they don't include table names outside of your module, such as `product`, `order`, etc... if so, delete those snapshots and regenerate again with `medusa db:generate`. You can also use the following prompt with your AI agent:
AI Agent Prompt ~~~md #### Cleaning Up Incorrect Snapshot Files A bug in earlier versions of Medusa caused `db:migrate` to generate snapshot files named after the database (e.g. `.snapshot-medusa.json`) instead of the module. In some cases, running `db:generate` afterward would overwrite the correct module snapshot with this full-database snapshot, causing the next generated migration to contain `DROP TABLE` statements for all Medusa core tables. Follow the steps below after updating to v2.15.2 that includes this fix. ##### Step 1: Delete database-name snapshots Look in each module's `migrations/` directory for snapshot files named after your database rather than the module. These are incorrectly generated files and should be deleted. They look like: ``` .snapshot-medusa.json .snapshot-my-store.json .snapshot-medusa-medusa-resolutions.json ``` The correct snapshot is named after the module: ``` .snapshot-.json ``` Delete any file that does not follow the module-name pattern. ##### Step 2: Check for corrupted module snapshots Open the remaining `.snapshot-.json` file for each module and check its `tables` array. It should only contain tables owned by that module. If it contains tables from other modules (e.g. `order`, `cart`, `product`, `customer` inside a small custom module), the snapshot was overwritten by the full-database snapshot and is corrupted. ##### Step 3: Regenerate corrupted snapshots For each corrupted snapshot: 1. Delete the corrupted snapshot file. 2. Regenerate it by running: ```bash npx medusa db:generate ``` ##### Step 4: Review the regenerated migration Open the newly created migration file and check its contents. If it contains `DROP TABLE` or unexpected `ALTER TABLE` statements for tables that belong to other modules: 1. **Do not run this migration.** 2. Delete the migration file. 3. The snapshot has now been regenerated correctly β€” subsequent runs of `db:generate` will produce accurate migrations. ~~~
##### Features * feat(medusa): enable index when querying products via promotion attribute values and enable sku search in products entrypoint by [@NicolasGorga](https://github.com/NicolasGorga) in [#15386](https://github.com/medusajs/medusa/pull/15386) ##### Bugs * fix(utils): disable generating snapshots on running migrations by [@shahednasser](https://github.com/shahednasser) in [#15382](https://github.com/medusajs/medusa/pull/15382) * fix: build should throw if medusa-config throws by [@peterlgh7](https://github.com/peterlgh7) in [#15383](https://github.com/medusajs/medusa/pull/15383) * fix(locking-redis): add jitter to Redis lock retry backoff by [@Suh0161](https://github.com/Suh0161) in [#15274](https://github.com/medusajs/medusa/pull/15274) ##### Chores * chore(docs): Generated References (automated) by [@app/github- _[Truncated at 4000 characters β€” full notes: https://github.com/medusajs/medusa/releases/tag/v2.15.2]_ ### v2.15.1 - Date: 2026-05-11 - Version: v2.15.1 - Original notes: https://github.com/medusajs/medusa/releases/tag/v2.15.1 - Permalink: https://whatsnew.fyi/product/medusa/releases/v2.15.1 ##### Highlights ###### Includes missing PRs from 2.15.0 release Due to an issue during the release process of `2.15.0`, several PRs listed in the release notes weren't included. If you've already installed `2.15.0`, you might have experienced behavior matching this description. If you want the changes listed in the release notes of said version, you should install this one instead. The issue in the release process has already been corrected. ##### Chores * chore(docs): Generated + Updated UI Reference (automated) by [@app/github-actions](https://github.com/app/github-actions) in [#15368](https://github.com/medusajs/medusa/pull/15368) * chore(docs): Update version in documentation (automated) by [@app/github-actions](https://github.com/app/github-actions) in [#15367](https://github.com/medusajs/medusa/pull/15367) * chore(docs): doc changes for next release (automated) by [@shahednasser](https://github.com/shahednasser) in [#15257](https://github.com/medusajs/medusa/pull/15257) **Full Changelog**: [v2.15.0...v2.15.1](https://github.com/medusajs/medusa/compare/v2.15.0...v2.15.1) ### v2.15.0 - Date: 2026-05-11 - Version: v2.15.0 - Original notes: https://github.com/medusajs/medusa/releases/tag/v2.15.0 - Permalink: https://whatsnew.fyi/product/medusa/releases/v2.15.0 ##### Highlights ###### Missing PRs in published packages Due to an issue during the release process, we identified several PRs listed in these release notes missing from the published packages. We recommend installing [2.15.1](https://github.com/medusajs/medusa/releases/tag/v2.15.1) instead. ###### Aligned Product and Variant Attribute Types 🚧 Breaking change This version aligns the `width`, `length`, `height`, and `weight` properties on the `Product` and `ProductVariant` data models to be of type `float`. In previous versions, their type was `text` on the `Product` data model, and `number` on the `ProductVariant` data model. This change only affects customizations that relied on the previous text type for these attributes, which are now expected to be float values. --- ###### Medusa Cloud Proxy Command The Medusa CLI now includes a `mcloud proxy` command for working with Medusa Cloud deployments, streamlining local development workflows against cloud environments. ```bash medusa mcloud proxy ``` [#15320](https://github.com/medusajs/medusa/pull/15320) --- ###### Promotion Context Hooks The promotion computation system now supports custom context hooks, allowing developers to pass additional context data when calculating promotions. This enables more sophisticated promotion rules based on external data sources or custom business logic. Example: ```ts // in src/workflows/hooks/promotion.ts import { StepResponse } from "@medusajs/framework/workflows-sdk"; import { updateCartPromotionsWorkflow } from "@medusajs/medusa/core-flows"; updateCartPromotionsWorkflow.hooks.setPromotionContext( ({ cart }, { container }) => { if (cart.items.length >= 2) { return new StepResponse({ company_id: "company_123" }); } } ); ``` [#15301](https://github.com/medusajs/medusa/pull/15301) --- ###### Product SKU Search Support The admin API now supports searching products by SKU, making it easier to find and manage products through their stock keeping unit identifiers. [#13930](https://github.com/medusajs/medusa/pull/13930) --- ###### Translation Copy Actions The admin dashboard translation edit page now includes copy actions for original translations, improving the translation workflow by allowing translators to quickly copy base text. [#14943](https://github.com/medusajs/medusa/pull/14943) ##### Features * feat(core-flows): add setPromotionContext hook to pass additional context for promotion computation by [@NicolasGorga](https://github.com/NicolasGorga) in [#15301](https://github.com/medusajs/medusa/pull/15301) * feat: Add mcloud proxy command to medusa CLI by [@sradevski](https://github.com/sradevski) in [#15320](https://github.com/medusajs/medusa/pull/15320) * feat(product): add SKU search support to admin API by [@bqst](https://github.com/bqst) in [#13930](https://github.com/medusajs/medusa/pull/13930) * feat(dashboard): add copy action for Original translations on translations edit page by [@LukasKri](https://github.com/LukasKri) in [#14943](https://github.com/medusajs/medusa/pull/14943) * fix(core-flows, payment, types): expose `metadata` on refund creation through `refundPaymentsWorkflow` by [@Metbcy](https://github.com/Metbcy) in [#15273](https://github.com/medusajs/medusa/pull/15273) ##### Bugs * fix(index): backfill missing inSchemaRef for existing parent entries by [@ranma-dev](https://github.com/ranma-dev) in [#15131](https://github.com/medusajs/medusa/pull/15131) * fix(workflows-sdk): flatten WorkflowData type to remove recursive expansion that caused TS excessive stack depth errors in large consumer codebases by [@NicolasGorga](https://github.com/NicolasGorga) in [#15174](https://github.com/medusajs/medusa/pull/15174) * fix(settings): mark Order computed status fields as non-filterable by [@aliaksei-loi](https://github.com/aliaksei-loi) in [#15262](https://github.com/medusajs/medu _[Truncated at 4000 characters β€” full notes: https://github.com/medusajs/medusa/releases/tag/v2.15.0]_