{"record":{"id":"78b9eb9ccc730a08","repo":"bmad-code-org/BMAD-METHOD","slug":"module-modulename-is-registered-as-a-marketpl","errorCode":null,"errorMessage":"Module '${moduleName}' is registered as a marketplace plugin but its skills could not be resolved from .claude-plugin/marketplace.json (missing or malformed on the selected channel). Aborting to avoid a partial install with no skills.","messagePattern":"Module '(.+?)' is registered as a marketplace plugin but its skills could not be resolved from \\.claude-plugin/marketplace\\.json \\(missing or malformed on the selected channel\\)\\. Aborting to avoid a partial install with no skills\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"tools/installer/modules/official-modules.js","lineNumber":293,"sourceCode":"\n    if (await fs.pathExists(targetPath)) {\n      await fs.remove(targetPath);\n    }\n\n    // Marketplace-plugin registry modules keep their installable skills outside\n    // the directory that holds module.yaml (sourcePath points at the -setup\n    // skill's assets/), so they cannot be installed by copying sourcePath. Copy\n    // the resolved skill directories instead, matching how custom marketplace\n    // installs lay out a module. Everything else (manifest, version info) flows\n    // through the standard external-module path below.\n    const moduleInfo = await this.externalModuleManager.getModuleByCode(moduleName);\n    if (moduleInfo && moduleInfo.marketplacePlugin) {\n      const pluginResolution = this.externalModuleManager.getPluginResolution(moduleName);\n      // Fail loud: copying sourcePath here would install only the -setup skill's\n      // assets/ (module.yaml + module-help.csv) and none of the skills — a\n      // silent, broken partial install. Abort instead.\n      if (!pluginResolution || !Array.isArray(pluginResolution.skillPaths) || pluginResolution.skillPaths.length === 0) {\n        throw new Error(\n          `Module '${moduleName}' is registered as a marketplace plugin but its skills could not be resolved ` +\n            `from .claude-plugin/marketplace.json (missing or malformed on the selected channel). ` +\n            `Aborting to avoid a partial install with no skills.`,\n        );\n      }\n      await this._copyResolvedSkills(pluginResolution, targetPath, fileTrackingCallback, options.moduleConfig);\n    } else {\n      await this.copyModuleWithFiltering(sourcePath, targetPath, fileTrackingCallback, options.moduleConfig);\n    }\n\n    if (!options.skipModuleInstaller) {\n      await this.createModuleDirectories(moduleName, bmadDir, options);\n    }\n\n    const { Manifest } = require('../core/manifest');\n    const manifestObj = new Manifest();\n    const versionInfo = await manifestObj.getModuleVersionInfo(moduleName, bmadDir, sourcePath);\n","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/bmad-code-org/BMAD-METHOD/blob/b70486b9bdcb0a404d329e2a763b57964e7f1360/tools/installer/modules/official-modules.js#L275-L311","documentation":"Thrown by OfficialModules.install() when a module is flagged as marketplacePlugin in the registry but getPluginResolution() returns null or an object with no skillPaths. This means the PluginResolver could not resolve any skills from the module's .claude-plugin/marketplace.json on the selected channel. The error is thrown deliberately to prevent a partial install that would have module.yaml but no actual skills.","triggerScenarios":"Installing a marketplace-plugin registry module where the cloned ref's .claude-plugin/marketplace.json is missing, malformed, or has no plugins with a skills array. The resolvePluginModule() method returned null and cached nothing in _pluginResolutions.","commonSituations":"The stable tag's marketplace.json was never created or was corrupted; the channel switch (stable to next or vice versa) pulled a ref where the marketplace.json doesn't match the expected schema; the plugin_name in the registry doesn't match any plugin in marketplace.json; the PluginResolver threw an error resolving all plugins.","solutions":["Reinstall with --next=<moduleName> to get the latest main branch which may have a valid marketplace.json.","Pin to a known-good tag that has a complete .claude-plugin/marketplace.json.","Verify the module's repository contains a valid .claude-plugin/marketplace.json with at least one plugin that has a skills array.","Check that the registry's plugin_name matches a plugin name in the marketplace.json."],"exampleFix":"# before — stable tag has malformed marketplace.json\nnpx bmad-method install\n# Error: skills could not be resolved from marketplace.json\n\n# after — use latest main\nnpx bmad-method install --next=my-module\n# or pin a known-good version\nnpx bmad-method install --pin my-module=v2.1.0","handlingStrategy":"fallback","validationCode":"// Pre-check marketplace-plugin resolution before install\nconst moduleInfo = await extMgr.getModuleByCode(moduleName);\nif (moduleInfo && moduleInfo.marketplacePlugin) {\n  // Force resolve on --next to get the latest marketplace.json\n  const resolved = await extMgr.resolvePluginModule(moduleName, options);\n  if (!resolved || !resolved.skillPaths || resolved.skillPaths.length === 0) {\n    throw new Error(`Cannot install marketplace plugin '${moduleName}': no skills resolvable. Try --next.`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await officialModules.install(moduleName, bmadDir, fileTrackingCallback, options);\n} catch (e) {\n  if (e.message.includes('skills could not be resolved')) {\n    // Retry with --next to get a potentially valid marketplace.json\n    console.log('Marketplace.json invalid on stable. Retrying with --next...');\n    await officialModules.install(moduleName, bmadDir, fileTrackingCallback, {\n      ...options,\n      channelOptions: { nextSet: new Set([moduleName]) },\n    });\n    return;\n  }\n  throw e;\n}","preventionTips":["Ensure marketplace-plugin repositories have a valid .claude-plugin/marketplace.json at every tagged release.","Use --next for modules whose stable tags have malformed marketplace.json.","Validate the marketplace.json schema before tagging a release.","Keep the registry's plugin_name in sync with the marketplace.json plugin names."],"tags":["marketplace","plugin-resolution","external-modules","install","partial-install-prevention"],"backgroundTag":null,"analyzedSha":"b70486b9bdcb0a404d329e2a763b57964e7f1360","analyzedAt":"2026-08-13T01:21:12.247Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}