mastra-ai/mastra · error
Directory already exists and is not empty: ${targetDir}
Error message
Directory already exists and is not empty: ${targetDir} What it means
scaffoldPlugin refuses to generate a new plugin into an existing, non-empty directory. Because scaffolding writes template files unconditionally, an occupied target directory would be overwritten or mixed with stale content; the guard prevents accidental data loss. The resolved target is projectRoot (default cwd) joined with the given targetDir.
Source
Thrown at mastracode/sdk/src/plugins/scaffold.ts:35
options: Pick<ScaffoldPluginOptions, 'projectRoot' | 'configDir'> = {},
): string {
if (isBarePluginName(target)) {
return path.join(
options.projectRoot ?? process.cwd(),
options.configDir ?? DEFAULT_CONFIG_DIR,
'plugins',
'sources',
'local',
target,
);
}
return path.resolve(options.projectRoot ?? process.cwd(), target);
}
export function scaffoldPlugin(targetDir: string, options: ScaffoldPluginOptions = {}): string {
const dir = resolveScaffoldTarget(targetDir, options);
if (fs.existsSync(dir) && fs.readdirSync(dir).length > 0) {
throw new Error(`Directory already exists and is not empty: ${targetDir}`);
}
const packageName =
path
.basename(dir)
.toLowerCase()
.replace(/[^a-z0-9_.-]+/g, '-')
.replace(/^-|-$/g, '') || 'mastracode-plugin';
const pluginId = options.id ?? packageName;
const pluginName = options.name ?? humanizeName(packageName);
fs.mkdirSync(path.join(dir, 'src'), { recursive: true });
fs.writeFileSync(
path.join(dir, 'package.json'),
`${JSON.stringify(
{
name: packageName,
type: 'module',View on GitHub (pinned to 75dd419e61)
Solutions
- Choose a new, unused target directory name and re-run the scaffold command.
- If the directory is leftover from a failed scaffold, delete it (verify contents first) and re-run.
- If you intended to scaffold there, move the existing files aside, scaffold, then restore what you need.
- Pass an explicit projectRoot option if the target resolved relative to the wrong cwd.
Example fix
// before $ mastracode plugin create my-plugin // Error: Directory already exists and is not empty: my-plugin // after — remove leftovers or use a fresh dir $ rm -rf my-plugin && mastracode plugin create my-plugin // or $ mastracode plugin create my-plugin-v2
Defensive patterns
Strategy: validation
Validate before calling
const target = path.resolve(projectRoot, targetDir);
if (fs.existsSync(target) && fs.readdirSync(target).length > 0) {
throw new Error(`Choose a different scaffold target; ${targetDir} is not empty`);
} Try / catch
try {
scaffoldPlugin(targetDir, { projectRoot });
} catch (err) {
if (err instanceof Error && err.message.includes('already exists and is not empty')) {
console.error(`Target occupied: ${err.message}. Pick a new name or clear the directory.`);
} else throw err;
} Prevention
- Check the target directory is absent or empty before scaffolding (fs.existsSync + readdirSync).
- Never pass "." or the repository root as targetDir.
- Clean up partially scaffolded directories after failed runs before retrying.
- Pass an explicit projectRoot so the target resolves where you expect.
When it happens
Trigger: Calling scaffoldPlugin(targetDir) or `mastracode create plugin <dir>` (prepare/createdDir flow) where resolveScaffoldTarget resolves to a path that already exists and fs.readdirSync shows at least one file, including hidden ones like .git or .DS_Store.
Common situations: Re-running a scaffold command after a partial/failed first attempt left files behind; scaffolding into a directory that already holds a real plugin; accidentally passing "." or the project root as targetDir, which always contains files.
Related errors
- Directory ${path.basename(targetPath)} already exists
- A file or directory named "${projectName}" already exists. P
- Skipped: Scorer ${filename} already exists at ${scorersPath}
- MASTRA_ENTRY_FILE_NOT_FOUND
- Failed to copy studio assets from "${studioSource}" to "${st
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/5bb4ac080477ea09.
Report an issue: GitHub.