paperclipai/paperclip · error · Error

bundled plugin "${key}" resolves to "${localPath}", outside

Error message

bundled plugin "${key}" resolves to "${localPath}", outside the bundled catalog root "${opts.catalogRoot}"; refusing to start

What it means

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.

Source

Thrown at server/src/services/bundled-plugins.ts:181

  const canonicalRoot = canonicalize(opts.catalogRoot);
  for (const key of keys) {
    if (seen.has(key)) continue;
    seen.add(key);
    const entry = BUNDLED_PLUGIN_CATALOG.find((candidate) => candidate.key === key);
    if (!entry) {
      const known = BUNDLED_PLUGIN_CATALOG.map((candidate) => candidate.key).join(", ");
      throw new Error(
        `bundled plugin auto-install key "${key}" is not in the bundled catalog (known keys: ${known}); refusing to start`,
      );
    }
    const override = entry.pathOverrideEnvVar
      ? opts.env[entry.pathOverrideEnvVar]?.trim()
      : undefined;
    const localPath = override
      ? path.resolve(override)
      : path.resolve(opts.catalogRoot, entry.relativePath);
    if (opts.enforceCatalogRoot && !isInsideRoot(canonicalize(localPath), canonicalRoot)) {
      throw new Error(
        `bundled plugin "${key}" resolves to "${localPath}", outside the bundled catalog root "${opts.catalogRoot}"; refusing to start`,
      );
    }
    resolved.push({ key: entry.key, pluginKey: entry.pluginKey, localPath });
  }
  return resolved;
}

interface RegistryPluginRow {
  id: string;
  pluginKey: string;
  status: string;
  version: string;
  manifestJson: PaperclipPluginManifestV1;
  lastError?: string | null;
}

export interface BundledPluginProvisionerDeps {

View on GitHub (pinned to 01ad858492)

Solutions

  1. Fix the bundled plugin mapping so the key resolves inside the catalog root.
  2. Investigate possible path traversal in the bundled plugin configuration.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/services/bundled-plugins.ts:181 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18). Data as JSON: /api/errors/0fd595e0c3b53e9a. Report an issue: GitHub.