mastra-ai/mastra · error · Error

Could not find a plugin entry file. Tried: ${ENTRY_CANDIDATE

Error message

Could not find a plugin entry file. Tried: ${ENTRY_CANDIDATES.join(', ')}

What it means

When no explicit entry is given, detectEntry probes a list of conventional entry candidates (ENTRY_CANDIDATES) inside the plugin directory. If none exists as a regular file, the SDK throws listing all tried candidates so the author knows what to create.

Source

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

    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);
  }

  for (const candidate of ENTRY_CANDIDATES) {
    const entryPath = path.join(pluginDir, candidate);
    if (fs.existsSync(entryPath) && fs.statSync(entryPath).isFile()) {
      return candidate;
    }
  }

  throw new Error(`Could not find a plugin entry file. Tried: ${ENTRY_CANDIDATES.join(', ')}`);
}

function isInsideDirectory(targetPath: string, root: string): boolean {
  return targetPath === root || targetPath.startsWith(root + path.sep);
}

async function runPluginInstallCommand(
  command: string,
  args: string[],
  execaOptions: typeof NON_INTERACTIVE_EXEC_OPTIONS & { cwd?: string },
  options: PluginInstallExecutionOptions,
): Promise<void> {
  const child = execa(command, args, {
    ...execaOptions,
    stdout: options.onOutput ? 'pipe' : 'ignore',
    stderr: options.onOutput ? 'pipe' : 'ignore',
    cancelSignal: options.signal,
  });

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Create one of the conventional entry files listed in the error message (typically `index.ts` at the plugin root).
  2. Set an explicit `entry` option pointing at your actual file, e.g. `entry: 'src/plugin.ts'`.
  3. Verify you are pointing the installer at the plugin's source directory, not `dist/` or a parent folder.
  4. Add a valid manifest declaring the plugin/entry if the convention differs.

Example fix

// before: plugin dir contains only plugin.ts, no config
mastra plugin install ./my-plugin

// after: specify the entry
mastra plugin install ./my-plugin --entry src/plugin.ts
// or add index.ts at the plugin root
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';
import path from 'node:path';
const CANDIDATES = ['index.ts', 'src/index.ts', 'plugin.ts', 'src/plugin.ts'];
export function hasEntryCandidate(pluginDir: string): boolean {
  return CANDIDATES.some(c => {
    const p = path.join(pluginDir, c);
    return fs.existsSync(p) && fs.statSync(p).isFile();
  });
}
// if false, pass an explicit `entry` option

Try / catch

try {
  await installPlugin(dir);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Could not find a plugin entry file')) {
    // fall back to explicit entry
    return installPlugin(dir, { entry: 'src/main.ts' });
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling entry/detectEntry(pluginDir) with no explicitEntry, no single manifest plugin, and none of the ENTRY_CANDIDATES paths existing as files in pluginDir.

Common situations: Plugin directories missing an index.ts/mastra equivalent; entry lives in `src/` while only `dist/` output exists; empty or mis-created plugin folder; entry file named unconventionally (e.g. `plugin.ts`) without configuring `entry`.

Related errors


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