medusajs/medusa · error · Error

Invalid modules configuration. Should be an array or object.

Error message

Invalid modules configuration. Should be an array or object.

What it means

Medusa validates the shape of the `modules` key in medusa-config. It accepts either an array of module declarations or an object map of `{ [serviceName]: declaration }`. Any other type (string, number, null-wrapped object) fails this guard.

Source

Thrown at packages/core/utils/src/common/define-config.ts:510

   */
  if (configModules) {
    if (isObject(configModules)) {
      const modules_ = (configModules ??
        {}) as unknown as Required<ConfigModule>["modules"]

      Object.entries(modules_).forEach(([key, moduleConfig]) => {
        modules.push({
          key,
          ...(isObject(moduleConfig)
            ? moduleConfig
            : { disable: !moduleConfig }),
        } as InputConfigModules[number])
      })
    } else if (Array.isArray(configModules)) {
      const modules_ = (configModules ?? []) as InternalModuleDeclaration[]
      modules.push(...(modules_ as InputConfigModules))
    } else {
      throw new Error(
        "Invalid modules configuration. Should be an array or object."
      )
    }
  }

  applyDefaultAuthMfaOptions(modules, authModuleOptions)

  return transformModules(modules, projectDir)
}

function normalizeProjectConfig(
  projectConfig: InputConfig["projectConfig"],
  { isCloud }: { isCloud: boolean }
): ConfigModule["projectConfig"] {
  const { http, redisOptions, sessionOptions, cloud, ...restOfProjectConfig } =
    projectConfig || {}

  const mergedCloudOptions: MedusaCloudOptions = {

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Change `modules` to an array of declarations or an object keyed by serviceName
  2. If computing modules dynamically, invoke the function before assigning: `modules: buildModules()`
  3. Re-run medusa after fixing the config

Example fix

// before
modules: "./src/modules/blog"
// after
modules: [{ resolve: "./src/modules/blog", key: "blog" }]
Defensive patterns

Strategy: type-guard

Validate before calling

const ok = Array.isArray(cfg.modules) || (typeof cfg.modules === 'object' && cfg.modules !== null)
if (!ok) throw new Error('modules must be array or object')

Type guard

const isModulesConfig = (m: unknown): m is Array<any> | Record<string, any> => Array.isArray(m) || (typeof m === 'object' && m !== null)

Prevention

When it happens

Trigger: Setting `modules: "@some/package"`, `modules: () => [...]`, or otherwise passing a non-array/non-object value in medusa-config.js modules; also YAML/JSON configs that stringify the value.

Common situations: Copy-pasting a config snippet where modules was a single string, dynamically computing modules with a function, or a typo like `modules: ["pkg"] merged incorrectly`.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/5d6575babef670c7. Report an issue: GitHub.