{"record":{"id":"0fd595e0c3b53e9a","repo":"paperclipai/paperclip","slug":"bundled-plugin-key-resolves-to-localpath","errorCode":null,"errorMessage":"bundled plugin \"${key}\" resolves to \"${localPath}\", outside the bundled catalog root \"${opts.catalogRoot}\"; refusing to start","messagePattern":"bundled plugin \"(.+?)\" resolves to \"(.+?)\", outside the bundled catalog root \"(.+?)\"; refusing to start","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/src/services/bundled-plugins.ts","lineNumber":181,"sourceCode":"  const canonicalRoot = canonicalize(opts.catalogRoot);\n  for (const key of keys) {\n    if (seen.has(key)) continue;\n    seen.add(key);\n    const entry = BUNDLED_PLUGIN_CATALOG.find((candidate) => candidate.key === key);\n    if (!entry) {\n      const known = BUNDLED_PLUGIN_CATALOG.map((candidate) => candidate.key).join(\", \");\n      throw new Error(\n        `bundled plugin auto-install key \"${key}\" is not in the bundled catalog (known keys: ${known}); refusing to start`,\n      );\n    }\n    const override = entry.pathOverrideEnvVar\n      ? opts.env[entry.pathOverrideEnvVar]?.trim()\n      : undefined;\n    const localPath = override\n      ? path.resolve(override)\n      : path.resolve(opts.catalogRoot, entry.relativePath);\n    if (opts.enforceCatalogRoot && !isInsideRoot(canonicalize(localPath), canonicalRoot)) {\n      throw new Error(\n        `bundled plugin \"${key}\" resolves to \"${localPath}\", outside the bundled catalog root \"${opts.catalogRoot}\"; refusing to start`,\n      );\n    }\n    resolved.push({ key: entry.key, pluginKey: entry.pluginKey, localPath });\n  }\n  return resolved;\n}\n\ninterface RegistryPluginRow {\n  id: string;\n  pluginKey: string;\n  status: string;\n  version: string;\n  manifestJson: PaperclipPluginManifestV1;\n  lastError?: string | null;\n}\n\nexport interface BundledPluginProvisionerDeps {","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/bundled-plugins.ts#L163-L199","documentation":"Path-containment guard in resolveBundledPluginInstalls: an env override resolved a bundled plugin's directory outside the canonical catalog root (e.g. via ../ or an absolute path). Refusing to start prevents loading arbitrary code outside the shipped, trusted catalog.","triggerScenarios":"Thrown at server/src/services/bundled-plugins.ts:181 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Fix the bundled plugin mapping so the key resolves inside the catalog root.","Investigate possible path traversal in the bundled plugin configuration."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}