github medusajs/medusa v2.16.0

7 hours ago

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:

update my Medusa project to v2.16.0

It will fetch the necessary changes needed to update your project.

Update Prompt for AI Agents
<role>
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.
</role>

<task>
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.
</task>

<context>
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.
</context>

<inputs>
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_SECRET` / `COOKIE_SECRET`.
- **Whether `react-router-dom` is a direct dependency.**
- **Whether custom code calls `manager.find` directly** (raw MikroORM access outside the module service abstractions).
</inputs>

<steps>
Work through these in order. For each, record findings and the proposed change in the plan — do not edit yet.

1. **Detect project shape and current version.** Read the relevant `package.json` files. Note standalone vs. monorepo and the storefront location (if any). Record the current `@medusajs/medusa` version.

2. **Plan the package version bump.** Identify every `@medusajs/*` dependency and devDependency across the backend (and admin/plugin packages if monorepo) and target `2.16.0`. Note that `@medusajs/ui` does not follow the `2.x` line — if it is a direct dependency anywhere (commonly in admin customizations), target `4.1.16` rather than `2.16.0`. If `react-router-dom` is a direct dependency anywhere (commonly in admin customizations or storefront), target `6.30.4`. Plan a single install/upgrade pass and note the package manager in use (yarn/npm/pnpm — detect from lockfile).

3. **Audit JWT and cookie secrets.** Check whether `http.jwtSecret` and `http.cookieSecret` are set in config or via `JWT_SECRET` / `COOKIE_SECRET` env vars. The default `supersecret` fallback is removed; in production a missing value throws at startup and the app fails to boot. If they are unset or still rely on the default, flag this as a **must-fix before deploying** item and propose setting them via environment variables. Never invent or hardcode secret values — instruct the user to generate strong secrets and set the env vars.

4. **Audit direct `manager.find` usage.** Search custom code for direct MikroORM `manager.find` calls that pass `fields`/`populate` referencing relations. Under MikroORM 6.6.14 these now throw if a referenced relation/property does not exist on the entity. For each occurrence, plan to validate field/populate paths against the entity metadata before the call (drop paths that don't map to a real property/relation), mirroring how Medusa prunes them internally. If no direct `manager.find` usage exists, record that this step is N/A.

5. **Plan ESLint plugin setup.** This is strongly recommended; once configured, `medusa build` and `medusa develop` lint by default and `medusa develop` fails to start on lint errors.
   - Add dev dependencies: `@medusajs/eslint-plugin`, `eslint`, and `jiti`. Install at the monorepo root for monorepos, or directly in the project for standalone projects (and in plugins). `jiti` is required: the config is written in TypeScript (`eslint.config.ts`), and ESLint 9 uses `jiti` to load and transpile a TS config file at runtime. Without it, linting fails to load the config.
   - Create the flat config (`eslint.config.ts`, or `.js`/`.mjs`):
     - **Standalone project / plugin:**
       ```ts
       import { defineConfig } from "eslint/config"
       import medusa from "@medusajs/eslint-plugin"

       export default defineConfig([...medusa.configs.recommended])
       ```
     - **Monorepo root** (`eslint.config.ts`): same as above.
     - **Monorepo backend** (\`apps/backend/eslint.config.ts\`): same as above.
   - Add `"eslint.config.*"` to the `exclude` array in the backend `tsconfig.json` to avoid type errors on the config file.
   - Add a `lint` script to the backend's `package.json` so the command is easy to run, e.g. `"lint": "medusa lint"`.
   - Note the new `medusa lint` command (supports `--fix` and `--quiet`) and the `--no-lint` flag for `medusa build` / `medusa develop`. Recommend running `medusa lint --fix` after upgrade and surfacing remaining lint errors to the user.

6. **Plan email verification config migration (backend).** Only if the project uses email verification.
   - Remove the `require_verification` option from the emailpass provider configuration.
   - Add `http.authVerificationsPerActor` under `projectConfig` in `medusa-config.*`. Its type is `Record<actorType, { entity_type: string; auth_provider: string }[]>`. An empty array for an actor type means no verification required. Example:
     ```ts
     http: {
       authVerificationsPerActor: {
         user: [],
         customer: [
           { entity_type: "email", auth_provider: "emailpass" },
         ],
       },
     }
     ```
   - Preserve the project's existing intent: map the previous `require_verification: true/false` (and any per-actor expectations) onto the new per-actor structure. Confirm with the user which actor types require verification if it is ambiguous.

7. **Plan the `auth.verification_requested` subscriber migration (backend).** Only if the project has a subscriber handling the `auth.verification_requested` event (search for `auth.verification_requested` or a `verificationRequestedHandler`). The event payload changed in v2.16.0:
   - `token` is renamed to **`code`** — use `code` to build the verification link.
   - `provider` is renamed to **`code_provider`** (defaults to `"token"`).
   - `actor_type` is **removed**. Replace the `actor_type !== "customer"` guard with an `entity_type` check, e.g. `if (entity_type !== "email") return`.
   - `provider_identity_id` is **removed**.
   - `entity_type` (e.g. `"email"`) and an optional `metadata?: Record<string, unknown>` are **added**. `entity_id` is still the email/identifier.

   Migration example:
   ```ts
   // Before
   export default async function verificationRequestedHandler({
     event: { data: { entity_id: email, token, actor_type } },
     container,
   }: SubscriberArgs<{
     entity_id: string
     token: string
     actor_type: string
     provider: string
     auth_identity_id: string
     provider_identity_id: string
     expires_at: string
   }>) {
     if (actor_type !== "customer") {
       return
     }
     // ...verification_url uses `token`
   }

   // After
   export default async function verificationRequestedHandler({
     event: { data: { entity_id: email, entity_type, code } },
     container,
   }: SubscriberArgs<{
     entity_id: string
     entity_type: string
     code_provider: string
     auth_identity_id: string
     code: string
     expires_at: string
     metadata?: Record<string, unknown>
   }>) {
     // only handle email verifications.
     if (entity_type !== "email") {
       return
     }
     // ...verification_url uses `code` instead of `token`
   }
   ```
   Update every reference inside the handler that used `token` to use `code` (including the `verification_url` built for the notification).

8. **Plan verification route migration.** Find any backend custom code, middleware, or storefront calls referencing the removed routes:
   - `/auth/[actor]/[provider]/verification/request` → `/auth/verification/request`
     - New request body: `{ entity_id: string, entity_type: string, code_provider?: string, metadata?: Record<string, unknown> }`. Response: `{ verification }`.
   - `/auth/[actor]/[provider]/verification/confirm` → `/auth/verification/confirm`
     - New request body: `{ code: string, code_provider?: string }`. Response: `{ entity_id, entity_type, code_provider, verified_at }`.

9. **Plan JS SDK signature migration (storefront / SDK consumers).** Update calls to match v2.16.0:
   - `auth.register(actor, method, payload)` — the previous `options` / `returnVerification` parameter is removed. The register call no longer reports whether verification is required.
   - `auth.login(actor, method, payload)` — now may return `{ verification_required: true, verification?, token }`. Verification is detected here, not at registration.
   - `auth.verification.request(body)` — signature changed to a single body object: `{ entity_id, entity_type, code_provider?, metadata? }` (no more `actor`/`method` positional args).
   - `auth.verification.confirm(body)` — signature changed to `{ code, code_provider? }` (token is passed as `code`).

   Migration examples:
   ```ts
   // Before
   const { verification_required } = await sdk.auth.register("customer", "emailpass", payload, { returnVerification: true })
   // After
   await sdk.auth.register("customer", "emailpass", payload)
   const loginResult = await sdk.auth.login("customer", "emailpass", payload)
   // loginResult may be { verification_required, token } when verification is needed

   // Before
   await sdk.auth.verification.request("customer", "emailpass", { entity_id: "customer@gmail.com" })
   await sdk.auth.verification.confirm("customer", "emailpass", { token })
   // After
   await sdk.auth.verification.request({ entity_id: "customer@gmail.com", entity_type: "email" })
   await sdk.auth.verification.confirm({ code: token })
   ```

10. **Plan storefront verification flow migration.** Only if a storefront with email verification exists. The flow moved verification from after registration to after login:
   - **Old flow:** register → register response says verification required → request verification → confirm → create customer + login.
   - **New flow:** register (get registration token) → redirect to login → login → login response says `verification_required` → call `/auth/verification/request` → user opens verify page with token → `/auth/verification/confirm` with `{ code: token }` → login again → create customer if needed → login again.
   - Plan the storefront page/route changes to implement the new ordering and the new SDK signatures from steps 8–9. If the storefront is a Medusa starter, note that updated starters already include this flow and the user may prefer to diff against the latest starter.

11. **Compile and present the migration plan** (see `<output_format>`). Then stop and wait for the user's approval. Do not edit any files until the user approves. If the user approves, apply the changes in dependency order (version bump and install first, then config, then code), and after each significant change note how to verify it.
</steps>

<constraints>
- Produce a plan first; make no file edits until the user explicitly approves it.
- Cover only the required/breaking changes listed above. Do not implement additive features (tax line context hook, multi-shipping carts, injection zones) even if you notice opportunities — mention them only if the user asks.
- Never hardcode or generate secret values into config or committed files. JWT/cookie secrets must come from environment variables; instruct the user to set strong values.
- Verify every API, route, config key, and SDK signature against https://docs.medusajs.com or the Medusa MCP server before relying on it. Do not guess.
- Match the project's existing code style (this is a TypeScript Medusa project: no semicolons, double quotes, 2-space indentation, parens on arrow functions). Never use emojis.
- If the storefront is not in this workspace, do not fabricate edits to it — surface the storefront steps as instructions for the user to apply in their storefront repo.
- Detect the package manager from the lockfile and use it consistently; do not assume npm.
</constraints>

<error_handling>
- If you cannot determine whether the project uses email verification, the package manager, or which actor types need verification, ask the user a targeted question rather than guessing.
- If a referenced file (e.g. `medusa-config.ts`, `tsconfig.json`) is missing or has an unexpected shape, report what you found and ask how to proceed instead of forcing an edit.
- If `manager.find` usage is ambiguous (e.g. dynamic field lists), flag it for manual review in the plan rather than rewriting it blindly.
- If the current version is already >= 2.16.0, report that and stop; do not downgrade or re-apply migrations.
</error_handling>

<output_format>
Present the plan as Markdown with these sections:

1. **Project summary** — shape (standalone/monorepo), current Medusa version, storefront presence, package manager.
2. **Applicable changes** — a checklist table: each in-scope change, whether it applies to this project (Yes/No/N/A), and a one-line reason.
3. **Proposed changes, in order** — for each applicable change: the files affected, the concrete edit (with before/after snippets where useful), and the command(s) to run.
4. **Must-fix before deploy** — items that will break a production boot or build if skipped (e.g. missing JWT/cookie secrets, lint errors blocking `medusa develop`).
5. **Manual verification steps** — how the user confirms each change worked after applying (e.g. `medusa build`, `medusa lint`, register/login/verify a test customer end-to-end).
6. **Out of scope / notes** — additive features intentionally skipped, and any storefront steps the user must apply in a separate repo.

End with an explicit line asking the user to approve the plan before you apply any changes.
</output_format>

<success_criteria>
- The plan covers every in-scope breaking change that applies to the project, and explicitly marks the rest N/A with a reason.
- No file is edited before user approval.
- Every proposed config key, route path, and SDK signature matches v2.16.0 (verified against the docs/MCP, not assumed).
- Secrets are handled via environment variables, never hardcoded.
- After approval and application, `medusa build` succeeds, `medusa lint` reports no errors, and (if email verification is used) a test register → login → verify → login flow completes end-to-end.
</success_criteria>

ESLint Plugin

To make development easier with Medusa, both for developers and AI agents, we've added a new ESLint plugin for Medusa applications. It catches issues that are either against Medusa conventions or may cause runtime errors if undetected.

All new Medusa projects come with the ESLint plugin installed by default. For existing users, we recommend installing it in your project as well. You can install the plugin without updating to this version of Medusa.

Learn more about the plugin in this documentation.

Install ESLint Plugin

To use the plugin, install it as a dev dependency along with ESLint-related plugins. For monorepo projects, install it in the root of the monorepo. For standalone Medusa projects, install it directly in the project:

// or use your package manager
pnpm install --save-dev @medusajs/eslint-plugin eslint jiti

Configure ESLint Plugin in Monorepo Projects

In your monorepository root, create eslint.config.ts with the following content:

import { defineConfig } from "eslint/config"
import medusa from "@medusajs/eslint-plugin"

export default defineConfig([...medusa.configs.recommended])

Then, create the file apps/backend/eslint.config.ts with the following content:

import { defineConfig } from "eslint/config"
import base from "../../eslint.config"

export default defineConfig([
  {
    extends: [base],
    // backend-specific overrides go here
    rules: {},
  },
])

Also, add eslint.config.* to the excluded files in apps/backend/tsconfig.json to avoid type errors on the file:

{
  "exclude": [
    // ...
    "eslint.config.*",
  ]
}

Configure ESLint Plugin in Standalone Project

In your standalone project (and plugins), create eslint.config.ts with the following content:

import { defineConfig } from "eslint/config"
import medusa from "@medusajs/eslint-plugin"

export default defineConfig([...medusa.configs.recommended])

Lint Project

The linting now works with eslint and your IDE if you have the ESLint plugin installed. If you upgrade to this version, you can also use Medusa's CLI for linting as explained in the next section.

Linting in Medusa Commands

🚧 Breaking change

If you setup the ESLint plugin and config in your Medusa backend, linting will run by default in the medusa build and medusa develop commands. If there are lint errors, both commands will fail.

You can disable the linting with the --no-lint flag on both commands:

pnpm medusa build --no-lint
pnpm medusa develop --no-lint

This release also includes a new lint command that runs the linting based on your configurations:

pnpm medusa lint

You can also pass options like --fix and --quiet.

Learn more in the CLI documentation.

MikroORM version bump to 6.6.14

🚧 Breaking change

MikroORM 6.6.12 is affected by CVE-2026-44680. This doesn't impact Medusa applications by default, but can affect Medusa customizations if they're JSON inputs are not properly validated with Zod.

This version updates MikroORM to 6.6.14. This comes with a breaking change in how MikroORM's manager.find method works. Previously, it ignored all relations that don't exist on an entity. Now, it will fail with an error.

This has been resolved internally by this PR. However, if you use manager.find in your code, we encourage you to look at the changes made in the PR and apply them in your code.

react-router-dom update

🚧 Breaking change

react-router-dom has also been updated to 6.30.4 due to a recent advisory. The previous version didn't impact Medusa applications; the update is a defensive measure only.

If you have react-router-dom installed in your application, make sure to update it to 6.30.4. Otherwise, admin customizations may break.

Email Verification Changes

🚧 Breaking change

Email verification has been expanded to support for general verification for any user information, such as email or phone number. Also, it now supports specifying different verification requirement per actor type.

In the previous version, The require_verification option of the Emailpass provider accepted a boolean value to enable or disable verification for all actor types. Now, this option has been removed. Instead, use the http.authVerificationsPerActor:

// medusa-config.ts

module.exports = defineConfig({
  projectConfig: {
    http: {
      authVerificationsPerActor: {
        user: [], // No verification required for users
        customer: [
          {
            entity_type: "email",
            auth_provider: "emailpass",
          }
        ]
      },
    },
    // ...
  },
  // ...
})

In this example, you require verification only for customers. The verification is for their email.

Learn more about setting up email verification in the backend in this documentation

Email Verification Flow Change

🚧 Breaking change

Following the above change, the email verification flow has now changed.

The default Medusa starter (dtc-starter) has been updated to include this new flow in the storefront by default.

In the previous version, you implemented the following flow for email verification in the storefront:

  1. Send a request to /auth/customer/emailpass/register to obtain a registration token.
  2. Request returns that the verification is required.
  3. Send a request to the /auth/customer/emailpass/verification/request route to request a verification token for the customer.
  4. The customer goes to the verification page in the storefront, with the token in the query parameter
  5. Send a request to the /auth/customer/emailpass/verification/confirm route to confirm the verification
  6. If verification is successful, create customer + login

In this version, the flow has changed to the following:

  1. Send a request to /auth/customer/emailpass/register to obtain a registration token.
  2. Request returns a successful response. Redirect the customer to the login page.
  3. Customer logs in. Send a request to /auth/customer/emailpass.
  4. Request returns that the verification is required.
  5. Send a request to the /auth/verification/request to request a verification token for the customer.
  6. The customer goes to the verification page in the storefront, with the token in the query parameter
  7. Send a request to the /auth/verification/confirm route to confirm the verification
  8. If verification is successful, create customer + login

Learn more about this new flow and how to implement it in this documentation

Change in Verification Routes

🚧 Breaking change

Following the above change in email verification flow, the following routes have been removed:

  • /auth/[actor]/[provider]/verification/request
  • /auth/[actor]/[provider]/verification/confirm

They've been replaced by the following routes:

  • /auth/verification/request
  • /auth/verification/confirm

Refer to the Admin and Store API references to learn more about these routes.

Change in JS SDK signature for email verification

🚧 Breaking change

The previous version introduced a new options parameter for the JS SDK's auth.register method that allows to configure the behavior when a registering user requires verification first. This option has been removed since the register route no longer returns whether verification is required, as explained in the verification flow changes section.

Instead, the sdk.auth.login route returns whether verification is required now. For example:

// Before
const { verification_required } = await sdk.auth.register(
  "customer",
  "emailpass",
  {
    email: "customer@gmail.com",
    password: "supersecret"
  },
  {
    returnVerification: true
  }
)

// After
// get registration token
await sdk.auth.register(
  "customer",
  "emailpass",
  {
    email: "customer@gmail.com",
    password: "supersecret"
  },
)

// later, login
const { verification_required } = await sdk.auth.login(
  "customer",
  "emailpass",
  {
    email: "customer@gmail.com",
    password: "supersecret"
  },
)

In addition, the signatures of the auth.verification.request and auth.verification.confirm have changed due to the changes to their routes:

// before
await sdk.auth.verification.request("customer", "emailpass", {
  entity_id: "customer@gmail.com"
})
await sdk.auth.verification.confirm("customer", "emailpass", {
  token
})

// after
await sdk.auth.verification.request({
  entity_id: "customer@gmail.com",
  entity_type: "email",
})
await sdk.auth.verification.confirm({ code: token })

Tax Line Context Hook

A new setTaxLineContext hook allows customization of tax calculation context, providing greater flexibility for complex tax scenarios. The hook is added to the cart's upsertTaxLinesWorkflow and updateTaxLinesWorkflow workflows, and the order's updateOrderTaxLinesWorkflow.

For example:

import { updateOrderTaxLinesWorkflow } from "@medusajs/medusa/core-flows";

updateOrderTaxLinesWorkflow.hooks.setTaxLineContext(
  async ({ order, items, shipping_methods }, { container }) => {
    // do something
  }
)

Multi-Shipping Method Cart Support

Carts now support multiple shipping methods of different shipping profiles, enabling split shipments and complex fulfillment scenarios. This allows customers to choose different shipping options for different items within the same order.

You can now pass an array of shipping methods to add to the cart in the /store/carts/:id/shipping-methods API route:

sdk.store.cart.addShippingMethod("cart_123", [
   // option 1 with shipping profile 1
   {
    option_id: "so_123",
    data: {
      // custom data for fulfillment provider.
    }
  },
   // option 2 with shipping profile 2
   {
    option_id: "so_456",
    data: {
      // custom data for fulfillment provider.
    }
  }
])

New Injection Zones

This release adds the following new injection zones in the admin dashboard:

// draft order pages
"draft_order.details.before"
"draft_order.details.after"
"draft_order.details.side.before"
"draft_order.details.side.after"
"draft_order.list.before"
"draft_order.list.after"

// gift card pages
"gift_card.details.before"
"gift_card.details.after"
"gift_card.details.side.before"
"gift_card.details.side.after"
"gift_card.list.before"
"gift_card.list.after"
"gift_card.list.side.before"
"gift_card.list.side.after"

// store credit account pages
"store_credit_account.details.before"
"store_credit_account.details.after"
"store_credit_account.details.side.before"
"store_credit_account.details.side.after"
"store_credit_account.list.before"
"store_credit_account.list.after"

Custom Injection Zones

The admin dashboard now supports adding custom injection zones in custom pages. This allows plugin developers to add widget injection zones in their UI routes.

Learn more in the Custom Injection Zones documentation.

Other dependency patches

This release bumps dependencies for OpenTelemetry and UUID due to recent security advisories in these packages. Medusa applications before this version are not impacted by these advisories, as we don't use any of the affected code, so this is a defensive measure only.

Tighten Payment webhook handling

This release handles edge cases when a payment provider's getWebhookActionAndData returns an undefined data.session_id field. Previously, this led to an arbitrary payment session being processed. Now, webhook handling exists early.

Properly escape JSON containment filters with Index Module

This release properly escapes single quotes in filters passed to the /store/products route when the Index Module is used. Previously, passing single quotes in filters like title caused SQL syntax errors. Now, single quotes are escaped in those filters.

Removed default JWT and Cookie secrets

This release removes the default supersecret value set for JWT and cookie secrets. In production, if those keys aren't set manually, the application will throw an error and fail to start.

Features

Bugs

  • fix(cli): replace unmaintained pg-god with direct pg.Pool CREATE DATA… by @dsumeet14 in #15635
  • fix: product organization combobox search and cache invalidation by @PrathamRanka in #15634
  • fix(dashboard): enforce locale-specific plural forms in translations by @radeknapora in #13268
  • fix(index): subscribe to restored events and re-index on restore by @Tusharkhadde in #15654
  • fix(payment-stripe): warn when webhookSecret is missing by @dsumeet14 in #15684
  • fix(dashboard): fix refund form rounding for sub-cent amounts by @Metbcy in #15349
  • fix(dashboard): prevent duplicate items in return create form by @Metbcy in #15348
  • fix: pin peter-evans/create-pull-request to a commit SHA (supply-chain hardening) by @eliottreich in #15664
  • fix(js-sdk): add RBAC ESM import extensions by @puneetdixit200 in #15597
  • fix(core-flows): skip tax on gift card line items when cart taxes are recalculated by @cainydev in #15545
  • fix(utils): InjectManager error message shows "undefined" instead of "baseRepository_" by @Tusharkhadde in #15662
  • fix(core-flows): apply customer-group price lists when creating a dra… by @shafi-VM in #15538
  • fix(medusa): allow updating buyget promotions via PATCH /admin/promotions/:id by @sanidhyasin in #15619
  • fix(medusa): type product category create response by @Zbl1007 in #15588
  • fix: correct "occured" → "occurred" typo in error messages and docs by @DucMinhNe in #15549
  • fix(product): Support non-Latin characters in product handles with Un… by @Cpidar in #15346
  • fix(admin): fix Copy API Key behavior in secret key created dialog by @Tusharkhadde in #15531
  • fix(plugin:develop): invoke yalc via process.execPath on Windows by @addemod in #15523
  • fix(medusa): clear session cookie on DELETE /auth/session by @shafi-VM in #15510
  • fix(medusa): include address_name in customer address defaults by @puneetdixit200 in #15511
  • fix(utils): preserve context index overrides by @puneetdixit200 in #15503
  • fix(core-flows): include shipping_method.name in tax calculation context by @NicolasGorga in #15575
  • fix(index): use parameterized binding for JSONB containment filter by @shahednasser in #15599
  • fix(framework): change for session cookies by @shahednasser in #15601
  • fix(utils,product): handle array of mikroORM entities serialization and fix variant image assignment serialization issue by @NicolasGorga in #15591
  • fix: use unique order country column id by @xonaib in #15486
  • fix: support csv mime types by @aritradhabal in #15483
  • fix(dashboard): preserve zero-amount shipping option prices on re-save by @Ultron03 in #15468
  • fix(dashboard): prevent crash when deleting the last image from product media gallery by @appinteractive in #15444
  • fix(file-local, core-flows): improve file resolution + invalid csv file handling by @shahednasser in #15558

Documentation

Chores

Other Changes

New Contributors

Full Changelog: v2.15.5...v2.16.0

Don't miss a new medusa release

NewReleases is sending notifications on new releases.