mastra-ai/mastra · error · Error
Plugin entry must be inside the plugin directory
Error message
Plugin entry must be inside the plugin directory
What it means
detectEntry validates that an explicitly provided entry file resolves to a path inside the plugin directory. If the resolved entry escapes the plugin root (via `..` or an absolute path outside it), the SDK throws to prevent loading code from arbitrary locations.
Source
Thrown at mastracode/sdk/src/plugins/install.ts:156
const detectedEntry = tryDetectEntry(pluginDir);
return detectedEntry ? [{ name: entry.name, path: pluginDir, entry: detectedEntry }] : [];
});
}
function tryDetectEntry(pluginDir: string): string | undefined {
try {
return detectEntry(pluginDir);
} catch {
return undefined;
}
}
export function detectEntry(pluginDir: string, explicitEntry?: string): string {
const root = path.resolve(pluginDir);
if (explicitEntry) {
const entryPath = path.resolve(pluginDir, explicitEntry);
if (!isInsideDirectory(entryPath, root)) {
throw new Error('Plugin entry must be inside the plugin directory');
}
if (fs.existsSync(entryPath) && fs.statSync(entryPath).isDirectory()) {
const nestedEntry = detectEntry(entryPath);
return path.relative(root, path.join(entryPath, nestedEntry));
}
if (path.extname(entryPath) !== '.ts') {
throw new Error('Plugin entry must be a .ts file');
}
if (!fs.existsSync(entryPath) || !fs.statSync(entryPath).isFile()) {
throw new Error(`Plugin entry file does not exist: ${explicitEntry}`);
}
return path.relative(root, entryPath);
}
const manifestPlugin = getSingleManifestPlugin(pluginDir);
if (manifestPlugin) {
return detectEntry(pluginDir, manifestPlugin.entry);
}View on GitHub (pinned to 75dd419e61)
Solutions
- Move the entry file inside the plugin directory and reference it relatively (e.g. `src/index.ts`).
- Remove `..` segments or absolute paths from the explicit entry setting.
- Omit the explicit entry and rely on auto-detection if the default candidates apply.
- If shared code is needed, publish/import it as a dependency rather than referencing it by path.
Example fix
// before
{ entry: '../shared/entry.ts' }
// after
{ entry: 'src/entry.ts' } // file lives inside the plugin dir Defensive patterns
Strategy: validation
Validate before calling
import path from 'node:path';
export function entryIsInside(pluginDir: string, entry: string): boolean {
const root = path.resolve(pluginDir);
const resolved = path.resolve(pluginDir, entry);
return resolved === root || resolved.startsWith(root + path.sep);
}
// call before install: entryIsInside(dir, entry) must be true Prevention
- Keep entries relative to the plugin root; never use `..` or absolute paths in `entry`.
- Vendor shared code into the plugin or depend on it as a package instead of path escapes.
- Review copied configs for stale out-of-tree entry paths.
When it happens
Trigger: Calling entry/detectEntry with an explicitEntry like `../shared/index.ts` or `/etc/something.ts` such that path.resolve(pluginDir, explicitEntry) fails the isInsideDirectory check against the resolved plugin dir.
Common situations: Config using `..` to reach shared code outside the plugin; passing an absolute path to a file in another repo; copying a config between projects where the entry now points outside the plugin dir.
Related errors
- Refusing to use local sandbox path outside configured root:
- Cookie password must be at least 32 characters for SSO. Set
- [MastraAuthGoogle] GOOGLE_COOKIE_PASSWORD is required for Go
- Cookie password must be at least 32 characters. Set OKTA_COO
- Invalid route path: "${path}". Path cannot contain '..', '?'
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/7c1510133846a8c5.
Report an issue: GitHub.