paperclipai/paperclip · error · Error

Choose either --canary or --version, not both.

Error message

Choose either --canary or --version, not both.

What it means

Mutually-exclusive channel selection guard in the npm install request resolver: the CLI's managed installer supports exactly one install channel per invocation, and the caller passed both the --canary dist-tag flag and an explicit --version pin. The request is rejected before any npm command runs.

Solutions

  1. Pass only one of --canary or --version.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at cli/src/commands/install.ts:97 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/c8dfb7730065778b. Report an issue: GitHub.

Appendix: source

Thrown at cli/src/commands/install.ts:97

    visited.add(packageName);
    ordered.push(entry);
  };

  visit("@paperclipai/server");
  return ordered;
}

export function assertSupportedNodeVersion(): void {
  if (!isSupportedNodeVersion(process.versions.node)) {
    throw new Error(`Installing or updating Paperclip requires Node.js ${MINIMUM_NODE_VERSION} or newer (found ${process.version} at ${process.execPath}). Put a supported Node bin directory first on PATH and run 'npx paperclipai@latest install --yes' to re-pin an existing managed install.`);
  }
}

export function resolveNpmInstallRequest(options: InstallOptions): {
  spec: string;
  channel: InstallChannel;
} {
  if (options.canary && options.version) throw new Error("Choose either --canary or --version, not both.");
  if (options.version) {
    const version = options.version.trim();
    if (!EXACT_VERSION_PATTERN.test(version)) {
      throw new Error(`--version requires an exact published version, received '${options.version}'.`);
    }
    return { spec: version, channel: "pinned" };
  }
  return options.canary ? { spec: "canary", channel: "canary" } : { spec: "latest", channel: "latest" };
}

function parseResolvedVersion(stdout: string): string {
  const trimmed = stdout.trim();
  if (!trimmed) throw new Error("npm returned an empty version response.");
  try {
    const parsed = JSON.parse(trimmed) as unknown;
    if (typeof parsed === "string") return parsed;
  } catch {
    if (EXACT_VERSION_PATTERN.test(trimmed)) return trimmed;

View on GitHub (pinned to 01ad858492)