bmad-code-org/BMAD-METHOD · error · Error

${label} is not a file: ${filePath}

Error message

${label} is not a file: ${filePath}

What it means

Thrown by assertReadableFile when the path exists but stat.isFile() is false — a directory or special file sits where a regular file is required. Lets the user distinguish a type mismatch from a missing/unreadable file.

Source

Thrown at tools/installer/core/install-paths.js:98

    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);
  } catch {
    throw new Error(`${label} is not readable: ${filePath}`);
  }
}

async function ensureWritableDir(dirPath, label) {
  const stat = await fs.stat(dirPath).catch(() => null);
  if (stat && !stat.isDirectory()) {
    throw new Error(`${label} exists but is not a directory: ${dirPath}`);
  }

  try {
    await fs.ensureDir(dirPath);
  } catch (error) {
    if (error.code === 'EACCES') {

View on GitHub (pinned to b70486b9bd)

Solutions

  1. Inspect the node: `ls -la <filePath>`.
  2. Remove the directory/symlink and restore the expected regular file (e.g. reinstall the package).
  3. Audit any tooling that may have created a directory in place of the file.
Defensive patterns

Strategy: validation

Validate before calling

const stat = await fs.stat(filePath).catch(() => null);
if (stat && !stat.isFile()) {
  // warn: a directory occupies the expected file path
}

Try / catch

try {
  await assertReadableFile(filePath, label);
} catch (error) {
  if (error.message.includes('is not a file')) { /* wrong type */ }
  throw error;
}

Prevention

When it happens

Trigger: assertReadableFile is called on a path (e.g. the package.json path) that resolves to a directory instead of a regular file.

Common situations: A directory was created with the same name as an expected file (e.g. someone ran `mkdir package.json`), or a symlink points at a directory where a file was expected.

Related errors


AI-assisted analysis of bmad-code-org/BMAD-METHOD@b70486b9bd (2026-08-13). Data as JSON: /api/errors/a1f35cc08c4da0f9. Report an issue: GitHub.