{"record":{"id":"5d6575babef670c7","repo":"medusajs/medusa","slug":"invalid-modules-configuration-should-be-an-array","errorCode":null,"errorMessage":"Invalid modules configuration. Should be an array or object.","messagePattern":"Invalid modules configuration\\. Should be an array or object\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/utils/src/common/define-config.ts","lineNumber":510,"sourceCode":"   */\n  if (configModules) {\n    if (isObject(configModules)) {\n      const modules_ = (configModules ??\n        {}) as unknown as Required<ConfigModule>[\"modules\"]\n\n      Object.entries(modules_).forEach(([key, moduleConfig]) => {\n        modules.push({\n          key,\n          ...(isObject(moduleConfig)\n            ? moduleConfig\n            : { disable: !moduleConfig }),\n        } as InputConfigModules[number])\n      })\n    } else if (Array.isArray(configModules)) {\n      const modules_ = (configModules ?? []) as InternalModuleDeclaration[]\n      modules.push(...(modules_ as InputConfigModules))\n    } else {\n      throw new Error(\n        \"Invalid modules configuration. Should be an array or object.\"\n      )\n    }\n  }\n\n  applyDefaultAuthMfaOptions(modules, authModuleOptions)\n\n  return transformModules(modules, projectDir)\n}\n\nfunction normalizeProjectConfig(\n  projectConfig: InputConfig[\"projectConfig\"],\n  { isCloud }: { isCloud: boolean }\n): ConfigModule[\"projectConfig\"] {\n  const { http, redisOptions, sessionOptions, cloud, ...restOfProjectConfig } =\n    projectConfig || {}\n\n  const mergedCloudOptions: MedusaCloudOptions = {","sourceCodeStart":492,"sourceCodeEnd":528,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/utils/src/common/define-config.ts#L492-L528","documentation":"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.","triggerScenarios":"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.","commonSituations":"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`.","solutions":["Change `modules` to an array of declarations or an object keyed by serviceName","If computing modules dynamically, invoke the function before assigning: `modules: buildModules()`","Re-run medusa after fixing the config"],"exampleFix":"// before\nmodules: \"./src/modules/blog\"\n// after\nmodules: [{ resolve: \"./src/modules/blog\", key: \"blog\" }]","handlingStrategy":"type-guard","validationCode":"const ok = Array.isArray(cfg.modules) || (typeof cfg.modules === 'object' && cfg.modules !== null)\nif (!ok) throw new Error('modules must be array or object')","typeGuard":"const isModulesConfig = (m: unknown): m is Array<any> | Record<string, any> => Array.isArray(m) || (typeof m === 'object' && m !== null)","tryCatchPattern":null,"preventionTips":["Typecheck medusa-config with @medusajs/types ConfigTypes","Compute modules eagerly, never assign a function"],"tags":["config","validation","medusa-config"],"backgroundTag":"config-type-mismatch","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}