paperclipai/paperclip · error

Worker entrypoint not found for plugin

Error message

Worker entrypoint not found for plugin "${plugin.pluginKey}". Checked: ${path.resolve(packageDir, workerRelPath)}, ${path.resolve(directDir, workerRelPath)}

What it means

Entrypoint resolution failure: the manifest's worker path was checked under the package dir and direct dir (with path-traversal protection) and existsSync failed for each candidate, and it is not an absolute existing path either. The plugin's missing/misdeclared worker entrypoint is at fault.

Solutions

  1. Build the plugin so the worker entrypoint exists at one of the checked paths, or fix the worker path in the manifest/package layout.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/services/plugin-loader.ts:2557 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-08-18). Data as JSON: /api/errors/4e46c4e962ad984b. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/plugin-loader.ts:2560

 * also the package directory if it was a local-path install.
 *
 * @see PLUGIN_SPEC.md §10 — Package Contract
 */
function resolveWorkerEntrypoint(
  plugin: PluginRecord & { packagePath?: string | null },
  localPluginDir: string,
): string {
  const manifest = plugin.manifestJson;
  const workerRelPath = manifest.entrypoints.worker;

  // For local-path installs we persist the resolved package path; use it first
  if (plugin.packagePath && existsSync(plugin.packagePath)) {
    const entrypoint = path.resolve(plugin.packagePath, workerRelPath);
    if (entrypoint.startsWith(path.resolve(plugin.packagePath)) && existsSync(entrypoint)) {
      return entrypoint;
    }
  }

  // Try the local plugin directory (standard npm install location)
  const packageName = plugin.packageName;
  let packageDir: string;

  if (packageName.startsWith("@")) {
    // Scoped package: @scope/plugin-name → localPluginDir/node_modules/@scope/plugin-name
    const [scope, name] = packageName.split("/");
    packageDir = path.join(localPluginDir, "node_modules", scope!, name!);
  } else {
    packageDir = path.join(localPluginDir, "node_modules", packageName);
  }

  // Also check if the package exists directly under localPluginDir
  // (for direct local-path installs or symlinked packages)
  const directDir = path.join(localPluginDir, packageName);

  // Try in order: node_modules path, direct path
  for (const dir of [packageDir, directDir]) {

View on GitHub (pinned to 3f1d897a7c)