mastra-ai/mastra · error · Error

Local plugin path does not exist or is not a directory: ${lo

Error message

Local plugin path does not exist or is not a directory: ${localPath}

What it means

installLocalPlugin resolves the given local path against the project root and validates it exists and is a directory before loading the plugin. If the path is missing or points to a file, installation cannot proceed and this error is thrown with the original (unresolved) path in the message.

Source

Thrown at mastracode/sdk/src/plugins/install.ts:43

  name: string;
  path: string;
  entry: string;
};

const ENTRY_CANDIDATES = ['src/index.ts', 'index.ts'];

export const NON_INTERACTIVE_GIT_ENV = { ...process.env, GIT_TERMINAL_PROMPT: '0' };

const NON_INTERACTIVE_EXEC_OPTIONS = { env: NON_INTERACTIVE_GIT_ENV };

export async function installLocalPlugin(
  localPath: string,
  scope: PluginScope,
  options: InstallPluginOptions,
): Promise<string> {
  const sourcePath = path.resolve(options.projectRoot, localPath);
  if (!fs.existsSync(sourcePath) || !fs.statSync(sourcePath).isDirectory()) {
    throw new Error(`Local plugin path does not exist or is not a directory: ${localPath}`);
  }

  const entry = detectEntry(sourcePath, options.entry);
  ensureMastraCodePackageLink(sourcePath);
  const plugin = await loadPluginFromEntry(path.join(sourcePath, entry));
  const registryPath = getPluginScopePaths(scope, options).registryPath;
  const registry = removePluginRecord(loadPluginRegistry(registryPath), plugin.id);
  const record: InstalledPluginRecord = {
    enabled: true,
    source: 'local',
    specifier: localPath,
    path: sourcePath,
    entry,
    ...(plugin.version ? { version: plugin.version } : {}),
  };

  savePluginRegistry(registryPath, setPluginRecord(registry, plugin.id, record));
  return plugin.id;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Verify the path exists: `ls <path>` from your project root; correct typos.
  2. Pass a directory (the plugin root containing package.json), not a source file.
  3. Use an absolute path if your process's project root differs from your shell cwd.
  4. Clone/checkout the local plugin first if it does not exist yet.

Example fix

// before
await sdk.plugins.install('./pluginz/my-plugin');

// after (correct spelling, directory, absolute)
await sdk.plugins.install('/home/me/code/my-plugin');
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';
import path from 'node:path';
export function assertLocalPluginDir(projectRoot: string, localPath: string): void {
  const p = path.resolve(projectRoot, localPath);
  if (!fs.existsSync(p) || !fs.statSync(p).isDirectory()) {
    throw new Error(`Local plugin path does not exist or is not a directory: ${localPath}`);
  }
}

Try / catch

try {
  await sdk.plugins.install(localPath);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Local plugin path does not exist')) {
    console.error(`Check the path relative to ${process.cwd()}: ${err.message}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling plugin install with a local specifier (e.g. a relative path) where path.resolve(projectRoot, localPath) either does not exist on disk or fs.statSync shows it is a file, not a directory.

Common situations: Typo in the path; running from a different working directory than expected so the relative path resolves elsewhere; pointing at the plugin's index.ts file instead of its root directory; plugin repo not cloned yet.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/49cb50d6cc6a2bf0. Report an issue: GitHub.