Repository: medusajs/medusa
Pull request #12025: fix: validate module names to disallow unallowed characters
Author: login: thetutlage
Labels: name: type: bug
name: team: medusa
Created: 2025-03-28T09:48:37Z | Merged: 2025-03-28T17:09:39Z



Diff:
diff --git a/.changeset/strange-sloths-hope.md b/.changeset/strange-sloths-hope.md
new file mode 100644
index 0000000000000..5e45256cb5e8c
--- /dev/null
+++ b/.changeset/strange-sloths-hope.md
@@ -0,0 +1,6 @@
+---
+"@medusajs/medusa": patch
+"@medusajs/utils": patch
+---
+
+fix: validate module names to disallow unallowed characters
diff --git a/packages/core/utils/src/common/__tests__/validate-module-name.spec.ts b/packages/core/utils/src/common/__tests__/validate-module-name.spec.ts
new file mode 100644
index 0000000000000..ffc81decbf01a
--- /dev/null
+++ b/packages/core/utils/src/common/__tests__/validate-module-name.spec.ts
@@ -0,0 +1,54 @@
+import { validateModuleName } from "../validate-module-name"
+
+describe("validateModuleName", function () {
+  it("should disallow variable unsafe module names", function () {
+    const expectations = [
+      {
+        input: "hello-world",
+        state: "fail",
+      },
+      {
+        input: "hello_world",
+        state: "pass",
+      },
+      {
+        input: "1st_plugin",
+        state: "fail",
+      },
+      {
+        input: "plugin_1st",
+        state: "pass",
+      },
+      {
+        input: "acme.module",
+        state: "fail",
+      },
+      {
+        input: "acme$module",
+        state: "fail",
+      },
+      {
+        input: "$module",
+        state: "fail",
+      },
+      {
+        input: "_private_module",
+        state: "pass",
+      },
+      {
+        input: "acme&corp_module",
+        state: "fail",
+      },
+    ]
+
+    expectations.forEach((expectation) => {
+      if (expectation.state === "fail") {
+        expect(() => validateModuleName(expectation.input)).toThrow(
+          `Invalid module name "${expectation.input}". Module names must be alpha numeric and may contain an underscore`
+        )
+      } else {
+        expect(() => validateModuleName(expectation.input)).not.toThrow()
+      }
+    })
+  })
+})
diff --git a/packages/core/utils/src/common/index.ts b/packages/core/utils/src/common/index.ts
index 34952511c2852..bb80855e8ff43 100644
--- a/packages/core/utils/src/common/index.ts
+++ b/packages/core/utils/src/common/index.ts
@@ -85,3 +85,4 @@ export * from "./unflatten-object-keys"
 export * from "./upper-case-first"
 export * from "./validate-handle"
 export * from "./wrap-handler"
+export * from "./validate-module-name"
diff --git a/packages/core/utils/src/common/validate-module-name.ts b/packages/core/utils/src/common/validate-module-name.ts
new file mode 100644
index 0000000000000..ab4b49e2952e6
--- /dev/null
+++ b/packages/core/utils/src/common/validate-module-name.ts
@@ -0,0 +1,25 @@
+/**
+ * Validates the module name to be variable safe. Since we generate
+ * a lot of code, types under the hood using the module name we
+ * have ensure that each module name is variable safe.
+ *
+ * Ofcourse, we can transform the module name to a variable safe value,
+ * but that might result into naming conflicts. For example: There are
+ * two module named as
+ *
+ * - sanity-products
+ * - sanity_products
+ *
+ * After transforming them, they will endup with the same output. This is
+ * a very simple example, but cases like these will lead to naming
+ * conflicts, so its better to use the names as it is and restrict
+ * them to be variable safe
+ */
+const RE = /^[a-zA-Z_][0-9a-zA-Z_]*$/
+export function validateModuleName(name: string) {
+  if (!RE.test(name)) {
+    throw new Error(
+      `Invalid module name "${name}". Module names must be alpha numeric and may contain an underscore`
+    )
+  }
+}
diff --git a/packages/medusa/src/loaders/index.ts b/packages/medusa/src/loaders/index.ts
index f0bbb3a2b38df..9ad7390271790 100644
--- a/packages/medusa/src/loaders/index.ts
+++ b/packages/medusa/src/loaders/index.ts
@@ -19,6 +19,7 @@ import {
   GraphQLSchema,
   mergePluginModules,
   promiseAll,
+  validateModuleName,
 } from "@medusajs/framework/utils"
 import { WorkflowLoader } from "@medusajs/framework/workflows"
 import { asValue } from "awilix"
@@ -150,6 +151,10 @@ export default async ({
   const plugins = await getResolvedPlugins(rootDirectory, configModule, true)
   mergePluginModules(configModule, plugins)
 
+  Object.keys(configModule.modules ?? {}).forEach((key) => {
+    validateModuleName(key)
+  })
+
   const linksSourcePaths = plugins.map((plugin) =>
     join(plugin.resolve, "links")
   )


Reviews:
user: login: carlos-r-l-rodrigues
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T13:27:56Z
user: login: olivermrbl
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T13:46:09Z
user: login: thetutlage
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T14:51:42Z
user: login: olivermrbl
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T14:54:20Z
user: login: thetutlage
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T15:05:06Z
user: login: thetutlage
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T15:21:13Z
user: login: olivermrbl
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T15:22:01Z

Review comments:
diff_hunk: @@ -0,0 +1,25 @@
+/**
+ * Validates the module name to be variable safe. Since we generate
+ * a lot of code, types under the hood using the module name we
+ * have ensure that each module name is variable safe.
+ *
+ * Ofcourse, we can transform the module name to a variable safe value,
+ * but that might result into naming conflicts. For example: There are
+ * two module named as
+ *
+ * - sanity-products
+ * - sanity_products
+ *
+ * After transforming them, they will endup with the same output. This is
+ * a very simple example, but cases like these will lead to naming
+ * conflicts, so its better to use the names as it is and restrict
+ * them to be variable safe
+ */
+const RE = /^[a-zA-Z_][0-9a-zA-Z_]*$/
+export function validateModuleName(name: string) {
+  if (!RE.test(name)) {
+    throw new Error(
+      `Invalid module name "${name}". Module names must be alpha numeric and may contain an underscore`
+    )
path: packages/core/utils/src/common/validate-module-name.ts
user: login: olivermrbl
body: suggestion: Should we log the error and skip the module registration to avoid the breaking change?
created_at: 2025-03-28T13:46:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,25 @@
+/**
+ * Validates the module name to be variable safe. Since we generate
+ * a lot of code, types under the hood using the module name we
+ * have ensure that each module name is variable safe.
+ *
+ * Ofcourse, we can transform the module name to a variable safe value,
+ * but that might result into naming conflicts. For example: There are
+ * two module named as
+ *
+ * - sanity-products
+ * - sanity_products
+ *
+ * After transforming them, they will endup with the same output. This is
+ * a very simple example, but cases like these will lead to naming
+ * conflicts, so its better to use the names as it is and restrict
+ * them to be variable safe
+ */
+const RE = /^[a-zA-Z_][0-9a-zA-Z_]*$/
+export function validateModuleName(name: string) {
+  if (!RE.test(name)) {
+    throw new Error(
+      `Invalid module name "${name}". Module names must be alpha numeric and may contain an underscore`
+    )
path: packages/core/utils/src/common/validate-module-name.ts
user: login: thetutlage
body: You mean still register the module?

Wouldn't that eventually fail when you will try to run migrations or generate GQL schema?
created_at: 2025-03-28T14:51:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,25 @@
+/**
+ * Validates the module name to be variable safe. Since we generate
+ * a lot of code, types under the hood using the module name we
+ * have ensure that each module name is variable safe.
+ *
+ * Ofcourse, we can transform the module name to a variable safe value,
+ * but that might result into naming conflicts. For example: There are
+ * two module named as
+ *
+ * - sanity-products
+ * - sanity_products
+ *
+ * After transforming them, they will endup with the same output. This is
+ * a very simple example, but cases like these will lead to naming
+ * conflicts, so its better to use the names as it is and restrict
+ * them to be variable safe
+ */
+const RE = /^[a-zA-Z_][0-9a-zA-Z_]*$/
+export function validateModuleName(name: string) {
+  if (!RE.test(name)) {
+    throw new Error(
+      `Invalid module name "${name}". Module names must be alpha numeric and may contain an underscore`
+    )
path: packages/core/utils/src/common/validate-module-name.ts
user: login: olivermrbl
body: Can we say with certainty that module names that don't follow these rules would have led to errors at some point, e.g. for running migrations? 

If that's the case, I'd be fine to proceed with this. But if not, I think we should log + skip the registration.
created_at: 2025-03-28T14:54:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,25 @@
+/**
+ * Validates the module name to be variable safe. Since we generate
+ * a lot of code, types under the hood using the module name we
+ * have ensure that each module name is variable safe.
+ *
+ * Ofcourse, we can transform the module name to a variable safe value,
+ * but that might result into naming conflicts. For example: There are
+ * two module named as
+ *
+ * - sanity-products
+ * - sanity_products
+ *
+ * After transforming them, they will endup with the same output. This is
+ * a very simple example, but cases like these will lead to naming
+ * conflicts, so its better to use the names as it is and restrict
+ * them to be variable safe
+ */
+const RE = /^[a-zA-Z_][0-9a-zA-Z_]*$/
+export function validateModuleName(name: string) {
+  if (!RE.test(name)) {
+    throw new Error(
+      `Invalid module name "${name}". Module names must be alpha numeric and may contain an underscore`
+    )
path: packages/core/utils/src/common/validate-module-name.ts
user: login: thetutlage
body: I can run some tests locally
created_at: 2025-03-28T15:05:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,25 @@
+/**
+ * Validates the module name to be variable safe. Since we generate
+ * a lot of code, types under the hood using the module name we
+ * have ensure that each module name is variable safe.
+ *
+ * Ofcourse, we can transform the module name to a variable safe value,
+ * but that might result into naming conflicts. For example: There are
+ * two module named as
+ *
+ * - sanity-products
+ * - sanity_products
+ *
+ * After transforming them, they will endup with the same output. This is
+ * a very simple example, but cases like these will lead to naming
+ * conflicts, so its better to use the names as it is and restrict
+ * them to be variable safe
+ */
+const RE = /^[a-zA-Z_][0-9a-zA-Z_]*$/
+export function validateModuleName(name: string) {
+  if (!RE.test(name)) {
+    throw new Error(
+      `Invalid module name "${name}". Module names must be alpha numeric and may contain an underscore`
+    )
path: packages/core/utils/src/common/validate-module-name.ts
user: login: thetutlage
body: Yes, I can confirm that using any of the unallowed values doesn't work. I cannot start the server
created_at: 2025-03-28T15:21:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,25 @@
+/**
+ * Validates the module name to be variable safe. Since we generate
+ * a lot of code, types under the hood using the module name we
+ * have ensure that each module name is variable safe.
+ *
+ * Ofcourse, we can transform the module name to a variable safe value,
+ * but that might result into naming conflicts. For example: There are
+ * two module named as
+ *
+ * - sanity-products
+ * - sanity_products
+ *
+ * After transforming them, they will endup with the same output. This is
+ * a very simple example, but cases like these will lead to naming
+ * conflicts, so its better to use the names as it is and restrict
+ * them to be variable safe
+ */
+const RE = /^[a-zA-Z_][0-9a-zA-Z_]*$/
+export function validateModuleName(name: string) {
+  if (!RE.test(name)) {
+    throw new Error(
+      `Invalid module name "${name}". Module names must be alpha numeric and may contain an underscore`
+    )
path: packages/core/utils/src/common/validate-module-name.ts
user: login: olivermrbl
body: Great, thanks for testing. Let's merge as is
created_at: 2025-03-28T15:22:01Z
author_association: CONTRIBUTOR

PR comments:
user: login: changeset-bot[bot]
created_at: 2025-03-28T09:48:41Z
body: ###  🦋  Changeset detected

Latest commit: d47e6eb97391684e5ea03ba004af77699ff353c8

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

<details><summary>This PR includes changesets to release 66 packages</summary>

  | Name                               | Type  |
| ---------------------------------- | ----- |
| @medusajs/medusa                   | Patch |
| @medusajs/utils                    | Patch |
| @medusajs/test-utils               | Patch |
| @medusajs/medusa-oas-cli           | Patch |
| integration-tests-http             | Patch |
| @medusajs/framework                | Patch |
| @medusajs/modules-sdk              | Patch |
| @medusajs/orchestration            | Patch |
| @medusajs/workflows-sdk            | Patch |
| @medusajs/cli                      | Patch |
| @medusajs/api-key                  | Patch |
| @medusajs/auth                     | Patch |
| @medusajs/cart                     | 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/region                   | Patch |
| @medusajs/sales-channel            | Patch |
| @medusajs/stock-location           | Patch |
| @medusajs/store                    | Patch |
| @medusajs/tax                      | Patch |
| @medusajs/user                     | Patch |
| @medusajs/workflow-engine-inmemory | Patch |
| @medusajs/workflow-engine-redis    | 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/auth-emailpass           | Patch |
| @medusajs/auth-github              | Patch |
| @medusajs/auth-google              | 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/js-sdk                   | Patch |
| @medusajs/types                    | 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 |

</details>

Not sure what this means? [Click here  to learn what changesets are](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add another changeset to this PR](https://github.com/medusajs/medusa/new/fix/module-name-validation?filename=.changeset/spotty-snakes-hammer.md&value=---%0A%22%40medusajs%2Fmedusa%22%3A%20patch%0A%22%40medusajs%2Futils%22%3A%20patch%0A---%0A%0Afix%3A%20validate%20module%20names%20to%20disallow%20unallowed%20characters%0A)


author_association: NONE
user: login: vercel[bot]
created_at: 2025-03-28T09:48:41Z
body: [vc]: #dl+buNLdXnm8IyhkGhUeL/PSqFl7cJWyZTTK7Pl4nU8=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJtZWR1c2EtZG9jcyIsInJvb3REaXJlY3RvcnkiOiJ3d3cvYXBwcy9kb2NzIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL21lZHVzYWpzL21lZHVzYS1kb2NzL0JxVndBdGoxc1g3NEs0WGJTSHJvTHM1R0c1VHUiLCJwcmV2aWV3VXJsIjoibWVkdXNhLWRvY3MtZ2l0LWZpeC1tb2R1bGUtbmFtZS12YWxpZGF0aW9uLW1lZHVzYWpzLnZlcmNlbC5hcHAiLCJuZXh0Q29tbWl0U3RhdHVzIjoiSUdOT1JFRCIsImxpdmVGZWVkYmFjayI6eyJyZXNvbHZlZCI6MCwidW5yZXNvbHZlZCI6MCwidG90YWwiOjAsImxpbmsiOiIifX0seyJuYW1lIjoiYXBpLXJlZmVyZW5jZSIsInJvb3REaXJlY3RvcnkiOiJ3d3cvYXBwcy9hcGktcmVmZXJlbmNlIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL21lZHVzYWpzL2FwaS1yZWZlcmVuY2UvRUdFMmRlU0ZOeTdMdHNibW5QeXhFejd0WFhjSCIsInByZXZpZXdVcmwiOiJhcGktcmVmZXJlbmNlLWdpdC1maXgtbW9kdWxlLW5hbWUtdmFsaWRhdGlvbi1tZWR1c2Fqcy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IlBFTkRJTkciLCJsaXZlRmVlZGJhY2siOnsicmVzb2x2ZWQiOjAsInVucmVzb2x2ZWQiOjAsInRvdGFsIjowLCJsaW5rIjoiYXBpLXJlZmVyZW5jZS1naXQtZml4LW1vZHVsZS1uYW1lLXZhbGlkYXRpb24tbWVkdXNhanMudmVyY2VsLmFwcCJ9fSx7Im5hbWUiOiJkb2NzLXVpIiwicm9vdERpcmVjdG9yeSI6Ind3dy9hcHBzL3VpIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL21lZHVzYWpzL2RvY3MtdWkvQ2VxdnV6d2pqazdlS2NEc3cxNzZCejFvWWNyQSIsInByZXZpZXdVcmwiOiJkb2NzLXVpLWdpdC1maXgtbW9kdWxlLW5hbWUtdmFsaWRhdGlvbi1tZWR1c2Fqcy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IklHTk9SRUQiLCJsaXZlRmVlZGJhY2siOnsicmVzb2x2ZWQiOjAsInVucmVzb2x2ZWQiOjAsInRvdGFsIjowLCJsaW5rIjoiIn19LHsibmFtZSI6Im1lZHVzYS1kYXNoYm9hcmQiLCJyb290RGlyZWN0b3J5IjoicGFja2FnZXMvYWRtaW4vZGFzaGJvYXJkIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL21lZHVzYWpzL21lZHVzYS1kYXNoYm9hcmQvQlE2RnBCOTlFTDJIOW03cFlVc0Z6Ynk4S244VyIsInByZXZpZXdVcmwiOiJtZWR1c2EtZGFzaGJvYXJkLWdpdC1maXgtbW9kdWxlLW5hbWUtdmFsaWRhdGlvbi1tZWR1c2Fqcy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6Im1lZHVzYS1kYXNoYm9hcmQtZ2l0LWZpeC1tb2R1bGUtbmFtZS12YWxpZGF0aW9uLW1lZHVzYWpzLnZlcmNlbC5hcHAifX0seyJuYW1lIjoicmVzb3VyY2VzLWRvY3MiLCJyb290RGlyZWN0b3J5Ijoid3d3L2FwcHMvcmVzb3VyY2VzIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL21lZHVzYWpzL3Jlc291cmNlcy1kb2NzLzhMam1mMjhwNmV5aFJQQlpYbWszanR0QkJGWFMiLCJwcmV2aWV3VXJsIjoicmVzb3VyY2VzLWRvY3MtZ2l0LWZpeC1tb2R1bGUtbmFtZS12YWxpZGF0aW9uLW1lZHVzYWpzLnZlcmNlbC5hcHAiLCJuZXh0Q29tbWl0U3RhdHVzIjoiSUdOT1JFRCIsImxpdmVGZWVkYmFjayI6eyJyZXNvbHZlZCI6MCwidW5yZXNvbHZlZCI6MCwidG90YWwiOjAsImxpbmsiOiIifX0seyJuYW1lIjoiYXBpLXJlZmVyZW5jZS12MiIsInJvb3REaXJlY3RvcnkiOiJ3d3cvYXBwcy9hcGktcmVmZXJlbmNlIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL21lZHVzYWpzL2FwaS1yZWZlcmVuY2UtdjIvRzI0UkJaZG1qdmJCTndEd1BGZTdzNjdOQ0RRdSIsInByZXZpZXdVcmwiOiJhcGktcmVmZXJlbmNlLXYyLWdpdC1maXgtbW9kdWxlLW5hbWUtdmFsaWRhdGlvbi1tZWR1c2Fqcy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IklHTk9SRUQiLCJsaXZlRmVlZGJhY2siOnsicmVzb2x2ZWQiOjAsInVucmVzb2x2ZWQiOjAsInRvdGFsIjowLCJsaW5rIjoiIn19LHsibmFtZSI6ImRvY3MtdjIiLCJyb290RGlyZWN0b3J5Ijoid3d3L2FwcHMvYm9vayIsImluc3BlY3RvclVybCI6Imh0dHBzOi8vdmVyY2VsLmNvbS9tZWR1c2Fqcy9kb2NzLXYyLzRodDdiUEJZcHR3ZGNMNnlkR2ZpRjVMY1ByWDIiLCJwcmV2aWV3VXJsIjoiZG9jcy12Mi1naXQtZml4LW1vZHVsZS1uYW1lLXZhbGlkYXRpb24tbWVkdXNhanMudmVyY2VsLmFwcCIsIm5leHRDb21taXRTdGF0dXMiOiJJR05PUkVEIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6IiJ9fSx7Im5hbWUiOiJ1c2VyLWd1aWRlIiwicm9vdERpcmVjdG9yeSI6Ind3dy9hcHBzL3VzZXItZ3VpZGUiLCJpbnNwZWN0b3JVcmwiOiJodHRwczovL3ZlcmNlbC5jb20vbWVkdXNhanMvdXNlci1ndWlkZS8zcXVZSHp4bjY4OVo3RWRHdmhQY3BhenBSUjJ1IiwicHJldmlld1VybCI6InVzZXItZ3VpZGUtZ2l0LWZpeC1tb2R1bGUtbmFtZS12YWxpZGF0aW9uLW1lZHVzYWpzLnZlcmNlbC5hcHAiLCJuZXh0Q29tbWl0U3RhdHVzIjoiSUdOT1JFRCIsImxpdmVGZWVkYmFjayI6eyJyZXNvbHZlZCI6MCwidW5yZXNvbHZlZCI6MCwidG90YWwiOjAsImxpbmsiOiIifX1dfQ==
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **api-reference** | 🔄 Building ([Inspect](https://vercel.com/medusajs/api-reference/EGE2deSFNy7LtsbmnPyxEz7tXXcH)) | [Visit Preview](https://api-reference-git-fix-module-name-validation-medusajs.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/api-reference-git-fix-module-name-validation-medusajs.vercel.app?via=pr-comment-feedback-link) | Mar 28, 2025 0:13am |
| **medusa-dashboard** | ✅ Ready ([Inspect](https://vercel.com/medusajs/medusa-dashboard/BQ6FpB99EL2H9m7pYUsFzby8Kn8W)) | [Visit Preview](https://medusa-dashboard-git-fix-module-name-validation-medusajs.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/medusa-dashboard-git-fix-module-name-validation-medusajs.vercel.app?via=pr-comment-feedback-link) | Mar 28, 2025 0:13am |

<details><summary>6 Skipped Deployments</summary>

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **api-reference-v2** | ⬜️ Ignored ([Inspect](https://vercel.com/medusajs/api-reference-v2/G24RBZdmjvbBNwDwPFe7s67NCDQu)) | [Visit Preview](https://api-reference-v2-git-fix-module-name-validation-medusajs.vercel.app) |  | Mar 28, 2025 0:13am |
| **docs-ui** | ⬜️ Ignored ([Inspect](https://vercel.com/medusajs/docs-ui/Ceqvuzwjjk7eKcDsw176Bz1oYcrA)) | [Visit Preview](https://docs-ui-git-fix-module-name-validation-medusajs.vercel.app) |  | Mar 28, 2025 0:13am |
| **docs-v2** | ⬜️ Ignored ([Inspect](https://vercel.com/medusajs/docs-v2/4ht7bPBYptwdcL6ydGfiF5LcPrX2)) | [Visit Preview](https://docs-v2-git-fix-module-name-validation-medusajs.vercel.app) |  | Mar 28, 2025 0:13am |
| **medusa-docs** | ⬜️ Ignored ([Inspect](https://vercel.com/medusajs/medusa-docs/BqVwAtj1sX74K4XbSHroLs5GG5Tu)) | [Visit Preview](https://medusa-docs-git-fix-module-name-validation-medusajs.vercel.app) |  | Mar 28, 2025 0:13am |
| **resources-docs** | ⬜️ Ignored ([Inspect](https://vercel.com/medusajs/resources-docs/8Ljmf28p6eyhRPBZXmk3jttBBFXS)) | [Visit Preview](https://resources-docs-git-fix-module-name-validation-medusajs.vercel.app) |  | Mar 28, 2025 0:13am |
| **user-guide** | ⬜️ Ignored ([Inspect](https://vercel.com/medusajs/user-guide/3quYHzxn689Z7EdGvhPcpazpRR2u)) | [Visit Preview](https://user-guide-git-fix-module-name-validation-medusajs.vercel.app) |  | Mar 28, 2025 0:13am |
</details>









author_association: NONE
user: login: thetutlage
created_at: 2025-03-28T09:50:11Z
body: /snapshot-this
author_association: CONTRIBUTOR
user: login: thetutlage
created_at: 2025-03-28T11:46:27Z
body: /snapshot-this
author_association: CONTRIBUTOR
user: login: thetutlage
created_at: 2025-03-28T12:05:13Z
body: /snapshot-this
author_association: CONTRIBUTOR
user: login: thetutlage
created_at: 2025-03-28T12:12:46Z
body: /snapshot-this
author_association: CONTRIBUTOR
user: login: thetutlage
created_at: 2025-03-28T15:21:21Z
body: /snapshot-this
author_association: CONTRIBUTOR