bmad-code-org/BMAD-METHOD · error · Error
Failed to clone external module '${moduleCode}' at ${resolve
Error message
Failed to clone external module '${moduleCode}' at ${resolved.version}: ${error.message} What it means
Thrown by cloneExternalModule() inside the git clone catch block when execSync('git clone ...') fails for an external module during a fresh clone (wasNewClone path). The error includes the module code, resolved version, and the underlying git error message.
Source
Thrown at tools/installer/modules/external-manager.js:431
if (wasNewClone) {
const fetchSpinner = await createSpinner();
fetchSpinner.start(`Fetching ${moduleInfo.name}...`);
try {
if (resolved.channel === 'next') {
execSync(`git clone --depth 1 "${moduleInfo.url}" "${moduleCacheDir}"`, {
stdio: ['ignore', 'pipe', 'pipe'],
env: gitEnv({ GIT_TERMINAL_PROMPT: '0' }),
});
} else {
execSync(`git clone --depth 1 --branch ${quoteShell(resolved.ref)} "${moduleInfo.url}" "${moduleCacheDir}"`, {
stdio: ['ignore', 'pipe', 'pipe'],
env: gitEnv({ GIT_TERMINAL_PROMPT: '0' }),
});
}
fetchSpinner.stop(`Fetched ${moduleInfo.name}`);
} catch (error) {
fetchSpinner.error(`Failed to fetch ${moduleInfo.name}`);
throw new Error(`Failed to clone external module '${moduleCode}' at ${resolved.version}: ${error.message}`);
}
}
// Record resolution (channel + tag + SHA) for the manifest writer to pick up.
const sha = execSync('git rev-parse HEAD', { cwd: moduleCacheDir, stdio: 'pipe', env: gitEnv() }).toString().trim();
ExternalModuleManager._resolutions.set(moduleCode, {
channel: resolved.channel,
version: resolved.version,
ref: resolved.ref,
sha,
repoUrl: moduleInfo.url,
resolvedFallback: !!resolved.resolvedFallback,
planSource: planEntry.source,
});
await writeChannelMarker(markerPath, { channel: resolved.channel, version: resolved.version, sha });
// Install dependencies if package.json exists
const packageJsonPath = path.join(moduleCacheDir, 'package.json');View on GitHub (pinned to b70486b9bd)
Solutions
- Verify the repository URL is accessible: try 'git clone <url>' manually.
- Check network connectivity and proxy/firewall settings.
- If the repo is private, ensure credentials are configured.
- Retry — transient network failures are common.
- If the tag was deleted upstream, switch to --next or a different --pin value.
Example fix
# before — repo moved or tag deleted npx bmad-method install --pin my-module=deleted-tag # after # Verify manually: git clone https://github.com/org/repo.git npx bmad-method install --next=my-module
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: verify repo is reachable
const { execSync } = require('child_process');
function isRepoReachable(url) {
try {
execSync(`git ls-remote --exit-code "${url}" HEAD`, { stdio: 'ignore', timeout: 15000 });
return true;
} catch {
return false;
}
}
const moduleInfo = await extMgr.getModuleByCode(moduleCode);
if (!isRepoReachable(moduleInfo.url)) {
throw new Error(`Repository ${moduleInfo.url} is not reachable`);
} Try / catch
for (let attempt = 1; attempt <= 3; attempt++) {
try {
await extMgr.cloneExternalModule(moduleCode, options);
break;
} catch (e) {
if (e.message.startsWith('Failed to clone external module') && attempt < 3) {
await new Promise(r => setTimeout(r, 2000 * attempt));
continue;
}
throw e;
}
} Prevention
- Verify the module's repository URL is accessible before installing.
- Configure credentials for private repositories.
- Retry on transient network failures.
- Use --next or a different --pin if the ref was deleted upstream.
When it happens
Trigger: The module's repository URL is unreachable or doesn't exist; the resolved ref (tag or branch) doesn't exist at clone time despite passing earlier validation; network failure; authentication required; the git binary is missing. This fires only when no cache existed and the initial clone fails.
Common situations: Repository was deleted or made private after being added to the registry; transient network outage; SSH key issues for git@ URLs; corporate proxy blocks the clone; the resolved tag was deleted between tagExists() and clone.
Related errors
- Failed to clone ${parsed.cloneUrl}${refSuffix}: ${error_.mes
- Could not resolve stable tag for '${moduleCode}' (${error.me
- Subdirectory '${parsed.subdir}' not found in cloned reposito
- Unsafe ref name: ${JSON.stringify(ref)}
- Tag '${planEntry.pin}' not found in ${parsed.owner}/${parsed
AI-assisted analysis of bmad-code-org/BMAD-METHOD@b70486b9bd (2026-08-13).
Data as JSON: /api/errors/67b169e0c4ea7763.
Report an issue: GitHub.