{"record":{"id":"8789580bfe54c9d3","repo":"paperclipai/paperclip","slug":"package-root-not-found-for-plugin-plugin-plugin","errorCode":null,"errorMessage":"Package root not found for plugin \"${plugin.pluginKey}\"","messagePattern":"Package root not found for plugin \"(.+?)\"","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/plugin-loader.ts","lineNumber":2584,"sourceCode":"    // Scoped package: @scope/plugin-name → localPluginDir/node_modules/@scope/plugin-name\n    const [scope, name] = packageName.split(\"/\");\n    packageDir = path.join(localPluginDir, \"node_modules\", scope!, name!);\n  } else {\n    packageDir = path.join(localPluginDir, \"node_modules\", packageName);\n  }\n\n  // Also check if the package exists directly under localPluginDir\n  // (for direct local-path installs or symlinked packages)\n  const directDir = path.join(localPluginDir, packageName);\n\n  // Try in order: node_modules path, direct path\n  for (const dir of [packageDir, directDir]) {\n    const entrypoint = path.resolve(dir, workerRelPath);\n\n    // Security: ensure entrypoint is actually inside the directory (prevent path traversal)\n    if (!entrypoint.startsWith(path.resolve(dir))) {\n      continue;\n    }\n\n    if (existsSync(entrypoint)) {\n      return entrypoint;\n    }\n  }\n\n  // Fallback: try the worker path as-is (absolute or relative to cwd)\n  // ONLY if it's already an absolute path and we trust the manifest (which we've already validated)\n  if (path.isAbsolute(workerRelPath) && existsSync(workerRelPath)) {\n    return workerRelPath;\n  }\n\n  throw new Error(\n    `Worker entrypoint not found for plugin \"${plugin.pluginKey}\". ` +\n      `Checked: ${path.resolve(packageDir, workerRelPath)}, ` +\n      `${path.resolve(directDir, workerRelPath)}`,\n  );\n}","sourceCodeStart":2566,"sourceCodeEnd":2602,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/plugin-loader.ts#L2566-L2602","documentation":"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.","triggerScenarios":"Thrown at server/src/services/plugin-loader.ts:2581 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["The plugin package root could not be resolved. Reinstall the plugin or verify its install directory was not moved or deleted."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}