{"record":{"id":"d4e1daf59ed363ad","repo":"bmad-code-org/BMAD-METHOD","slug":"module-modulecode-was-downloaded-but-its-modu","errorCode":null,"errorMessage":"Module '${moduleCode}' was downloaded but its module definition was not found. Expected '${moduleDefinitionPath}' to exist in ${versionHint}, but it is missing. The repository may have been restructured after this release was tagged.${channelHint}","messagePattern":"Module '(.+?)' was downloaded but its module definition was not found\\. Expected '(.+?)' to exist in (.+?), but it is missing\\. The repository may have been restructured after this release was tagged\\.(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"tools/installer/modules/external-manager.js","lineNumber":581,"sourceCode":"      }\n    }\n\n    // Check repo root as last fallback\n    const rootCandidate = path.join(cloneDir, 'module.yaml');\n    if (await fs.pathExists(rootCandidate)) {\n      return path.dirname(rootCandidate);\n    }\n\n    // Nothing found: the cloned ref does not contain a recognizable module structure.\n    // This happens when a stable tag predates a module restructure (e.g. the repo\n    // moved files from payload/ to skills/ after the tag was cut). Returning a\n    // non-existent path silently causes a confusing ENOENT deep inside copyModuleWithFiltering;\n    // throw a descriptive error here instead so the user knows what happened and how to recover.\n    const resolution = ExternalModuleManager._resolutions.get(moduleCode);\n    const versionHint = resolution?.version ? `version ${resolution.version}` : 'the cloned version';\n    const channelHint =\n      resolution?.channel === 'stable' ? ` Try reinstalling with \\`--next=${moduleCode}\\` to use the latest main branch instead.` : '';\n    throw new Error(\n      `Module '${moduleCode}' was downloaded but its module definition was not found. ` +\n        `Expected '${moduleDefinitionPath}' to exist in ${versionHint}, but it is missing. ` +\n        `The repository may have been restructured after this release was tagged.${channelHint}`,\n    );\n  }\n\n  /**\n   * Resolve a marketplace-plugin registry module to an installable plugin\n   * definition. Clones the repo (respecting the channel plan), reads its\n   * .claude-plugin/marketplace.json, and runs the PluginResolver against the\n   * plugin matching this module. The result (skillPaths + module.yaml +\n   * module-help.csv) is cached so install() can copy the resolved skill dirs.\n   *\n   * @param {string} moduleCode - Code of the external module\n   * @param {Object} options - Options passed to cloneExternalModule\n   * @returns {Promise<Object|null>} ResolvedModule from PluginResolver, or null\n   *   when the module is not a marketplace plugin or cannot be resolved.\n   */","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/bmad-code-org/BMAD-METHOD/blob/b70486b9bdcb0a404d329e2a763b57964e7f1360/tools/installer/modules/external-manager.js#L563-L599","documentation":"Thrown by findExternalModuleSource() when a module was successfully cloned but no module.yaml file can be found at the registry-configured moduleDefinition path, nor in fallback locations (skills/, src/, repo root). This typically means the stable tag predates a repository restructuring where module files were moved.","triggerScenarios":"Installing a module from a 'stable' channel tag that was cut before the repo moved its module.yaml (e.g., from payload/ to skills/). After cloning, findExternalModuleSource checks moduleInfo.moduleDefinition, then skills/module.yaml, src/module.yaml, and root — all miss.","commonSituations":"An old stable tag (e.g., v1.0.0) was released before a major repo restructure; the moduleDefinition path in bmad-modules.yaml is stale; a tag was cut from a branch that didn't have the module layout yet.","solutions":["Reinstall with --next=<moduleCode> to use the latest main branch, which has the current file layout.","Pin to a newer stable tag that was released after the restructure.","Update bmad-modules.yaml's module_definition path to match the old tag's layout (if you control the registry).","Verify the module's repository structure on GitHub for the tagged version."],"exampleFix":"# before — old stable tag predates restructure\nnpx bmad-method install\n# Error: module definition not found in version v1.0.0\n\n# after — use latest main\nnpx bmad-method install --next=my-module\n# or pin a newer release\nnpx bmad-method install --pin my-module=v2.0.0","handlingStrategy":"fallback","validationCode":"// Check if the module's definition path exists at the target tag before committing to stable\nconst { execSync } = require('child_process');\n\nfunction checkFileAtTag(url, tag, filePath) {\n  try {\n    execSync(`git ls-remote --exit-code ${url} refs/tags/${tag}`, { stdio: 'ignore' });\n    // For a deeper check, use the GitHub API to verify the file exists at the tag\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n// Prefer --next for modules that have recently restructured\nconst moduleInfo = await extMgr.getModuleByCode(moduleCode);\nif (moduleInfo && recentlyRestructured(moduleInfo)) {\n  options.channelOptions = { nextSet: new Set([moduleCode]) };\n}","typeGuard":null,"tryCatchPattern":"try {\n  await officialModules.findModuleSource(moduleCode, options);\n} catch (e) {\n  if (e.message.includes('module definition was not found')) {\n    // Switch to --next to get the current repo layout\n    console.log('Stable tag has old layout. Retrying with --next...');\n    await officialModules.findModuleSource(moduleCode, {\n      ...options,\n      channelOptions: { nextSet: new Set([moduleCode]) },\n    });\n    return;\n  }\n  throw e;\n}","preventionTips":["Use --next for modules that have recently undergone repository restructuring.","Pin to tags known to have the current file layout.","Keep the registry's module_definition path in sync with the repository structure.","When cutting stable tags, ensure module.yaml exists at the expected path."],"tags":["git","repository-structure","external-modules","version-mismatch","module-definition"],"backgroundTag":null,"analyzedSha":"b70486b9bdcb0a404d329e2a763b57964e7f1360","analyzedAt":"2026-08-13T01:21:12.247Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}