{"record":{"id":"b442ab81431df461","repo":"bmad-code-org/BMAD-METHOD","slug":"module-modulename-not-found-in-any-source-loc","errorCode":null,"errorMessage":"Module '${moduleName}' not found in any source location","messagePattern":"Module '(.+?)' not found in any source location","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"tools/installer/modules/official-modules.js","lineNumber":438,"sourceCode":"      // lines show the same string we just wrote to disk (custom git-backed\n      // installs show the cloned ref or 'main').\n      versionInfo: {\n        version: resolved.cloneRef || (hasGitClone ? 'main' : resolved.version || ''),\n      },\n    };\n  }\n\n  /**\n   * Update an existing module\n   * @param {string} moduleName - Name of the module to update\n   * @param {string} bmadDir - Target bmad directory\n   */\n  async update(moduleName, bmadDir) {\n    const sourcePath = await this.findModuleSource(moduleName);\n    const targetPath = path.join(bmadDir, moduleName);\n\n    if (!sourcePath) {\n      throw new Error(`Module '${moduleName}' not found in any source location`);\n    }\n\n    if (!(await fs.pathExists(targetPath))) {\n      throw new Error(`Module '${moduleName}' is not installed`);\n    }\n\n    await this.syncModule(sourcePath, targetPath);\n\n    return {\n      success: true,\n      module: moduleName,\n      path: targetPath,\n    };\n  }\n\n  /**\n   * Remove a module\n   * @param {string} moduleName - Name of the module to remove","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/bmad-code-org/BMAD-METHOD/blob/b70486b9bdcb0a404d329e2a763b57964e7f1360/tools/installer/modules/official-modules.js#L420-L456","documentation":"Thrown by OfficialModules.update when findModuleSource(moduleName) returns null. findModuleSource checks the built-in 'core' and 'bmm' modules, then external official modules (via externalModuleManager, honoring channelOptions), then custom modules already cloned to cache; null means none recognized the code. Update refuses to proceed without a source to sync from.","triggerScenarios":"Calling installer.update('somemodule', bmadDir) where 'somemodule' is neither 'core', 'bmm', a registered external official module for the configured channel, nor a previously-cloned custom module. Also when channelOptions hide an external module that would otherwise resolve.","commonSituations":"A custom-source module whose clone cache was cleared; module code misspelled vs. the directory name in _bmad/; the external module registry changed or network/channel misconfiguration hides the module; running update from a different cwd so getProjectRoot resolves source paths incorrectly.","solutions":["Confirm the module code matches the installed directory name under _bmad/ and the entry in _bmad/manifest.json.","For custom-source modules, re-run install with the original --custom-source <url> to repopulate the clone cache, then retry update.","Run from the repo root so findModuleSource's getProjectRoot resolves built-in sources correctly.","Verify the external module is still listed in the registry for your channel (--all-stable / --pin can change visibility)."],"exampleFix":"// before: update fails because custom-source cache was cleared\n//   await modules.update('myplugin', bmadDir);  // -> Module 'myplugin' not found\n//\n// after: re-establish the source first\n//   await modules.installFromResolution(\n//     customMgr.resolveSource('https://github.com/me/myplugin', ...),\n//     bmadDir,\n//   );\n//   await modules.update('myplugin', bmadDir);","handlingStrategy":"validation","validationCode":"const sourcePath = await modules.findModuleSource(moduleName, { channelOptions });\nif (!sourcePath) {\n  console.error(`No source for ${moduleName}; reinstall via --custom-source or check the channel.`);\n  return;\n}\nawait modules.update(moduleName, bmadDir);","typeGuard":null,"tryCatchPattern":"try {\n  await modules.update(moduleName, bmadDir);\n} catch (e) {\n  if (/not found in any source location/.test(e.message)) {\n    // re-establish source then retry, or skip\n    await modules.installFromResolution(customMgr.resolveSource(url, opts), bmadDir);\n    await modules.update(moduleName, bmadDir);\n  } else { throw e; }\n}","preventionTips":["Keep the custom-source URL recorded (e.g. in _bmad/manifest.json rawSource) so updates can re-clone.","Run install/update from the repo root so findModuleSource's getProjectRoot resolves built-in sources.","Don't clear the clone cache between install and update."],"tags":["installer","module-resolution","update","custom-source"],"backgroundTag":null,"analyzedSha":"b70486b9bdcb0a404d329e2a763b57964e7f1360","analyzedAt":"2026-08-13T01:21:12.247Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}