paperclipai/paperclip · error

Package root not found for plugin

Error message

Package root not found for plugin "${plugin.pluginKey}"

What it means

Root resolution guard in resolvePluginPackageRoot: neither the recorded packagePath nor the node_modules layout nor the direct localPluginDir/packageName location exists. The plugin's files were removed or never installed; the missing package directory is at fault.

Solutions

  1. The plugin package root could not be resolved. Reinstall the plugin or verify its install directory was not moved or deleted.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/services/plugin-loader.ts:2581 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/8789580bfe54c9d3. Report an issue: GitHub.

Appendix: source

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

    // 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]) {
    const entrypoint = path.resolve(dir, workerRelPath);

    // Security: ensure entrypoint is actually inside the directory (prevent path traversal)
    if (!entrypoint.startsWith(path.resolve(dir))) {
      continue;
    }

    if (existsSync(entrypoint)) {
      return entrypoint;
    }
  }

  // Fallback: try the worker path as-is (absolute or relative to cwd)
  // ONLY if it's already an absolute path and we trust the manifest (which we've already validated)
  if (path.isAbsolute(workerRelPath) && existsSync(workerRelPath)) {
    return workerRelPath;
  }

  throw new Error(
    `Worker entrypoint not found for plugin "${plugin.pluginKey}". ` +
      `Checked: ${path.resolve(packageDir, workerRelPath)}, ` +
      `${path.resolve(directDir, workerRelPath)}`,
  );
}

View on GitHub (pinned to 3f1d897a7c)