bmad-code-org/BMAD-METHOD · error · Error
${label} is not a directory: ${dirPath}
Error message
${label} is not a directory: ${dirPath} What it means
Thrown by assertReadableDir when the path exists (stat succeeds) but stat.isDirectory() is false — a regular file or special file sits where a directory is required. Distinct from the not-exist and not-readable cases so the user knows the path is the wrong type.
Source
Thrown at tools/installer/core/install-paths.js:83
}
helpCatalog() {
return path.join(this.configDir, 'bmad-help.csv');
}
moduleDir(name) {
return path.join(this.bmadDir, name);
}
moduleConfig(name) {
return path.join(this.bmadDir, name, 'config.yaml');
}
}
async function assertReadableDir(dirPath, label) {
const stat = await fs.stat(dirPath).catch(() => null);
if (!stat) {
throw new Error(`${label} does not exist: ${dirPath}`);
}
if (!stat.isDirectory()) {
throw new Error(`${label} is not a directory: ${dirPath}`);
}
try {
await fs.access(dirPath, fs.constants.R_OK);
} catch {
throw new Error(`${label} is not readable: ${dirPath}`);
}
}
async function assertReadableFile(filePath, label) {
const stat = await fs.stat(filePath).catch(() => null);
if (!stat) {
throw new Error(`${label} does not exist: ${filePath}`);
}
if (!stat.isFile()) {
throw new Error(`${label} is not a file: ${filePath}`);
}
try {
await fs.access(filePath, fs.constants.R_OK);View on GitHub (pinned to b70486b9bd)
Solutions
- Inspect the path with `ls -la <dirPath>` to confirm what type of node occupies it.
- Remove or rename the offending file so the expected directory can be used.
- Re-extract/reinstall the package so directory structure is correct.
Defensive patterns
Strategy: validation
Validate before calling
const stat = await fs.stat(dirPath).catch(() => null);
if (stat && !stat.isDirectory()) {
// surface a friendly error before the installer throws
} Try / catch
try {
await assertReadableDir(dirPath, label);
} catch (error) {
if (error.message.includes('is not a directory')) { /* wrong type */ }
throw error;
} Prevention
- Confirm expected paths are directories before install.
- Avoid creating files whose names collide with required directories.
When it happens
Trigger: InstallPaths.create() validates a directory path that is occupied by a file. E.g. srcDir resolves to a path where a file named like the expected directory exists.
Common situations: A file was accidentally created with the same name as an expected directory, a symlink points to a file instead of a directory, or a packaging step shipped a file where a directory was expected.
Related errors
- ${label} does not exist: ${dirPath}
- ${label} is not readable: ${dirPath}
- ${label} does not exist: ${filePath}
- ${label} is not a file: ${filePath}
- ${label} is not readable: ${filePath}
AI-assisted analysis of bmad-code-org/BMAD-METHOD@b70486b9bd (2026-08-13).
Data as JSON: /api/errors/60fae6319285acb1.
Report an issue: GitHub.