paperclipai/paperclip · info

Downgrade cancelled. Re-run with --yes to confirm explicitly

Error message

Downgrade cancelled. Re-run with --yes to confirm explicitly.

What it means

Thrown by updateCommand on the global-npm path when the resolved target version is older than the currently installed version (compareVersions returns negative), options.yes is not true, and the downgrade confirmation prompt returns false. Downgrades are gated because they can roll back migrations/features, so explicit consent is required.

Source

Thrown at cli/src/commands/update.ts:221

    try {
      restarted = await (overrides.restartActiveService ?? restartActiveManagedService)(installed.version);
    } catch (error) {
      return rollbackAfterServiceValidationFailure(
        paths,
        overrides.restartActiveService ?? restartActiveManagedService,
        error,
        "Updated git payload",
      );
    }
    emit(options, { mode, source: "git", changed: true, currentSha: manifest.sha, targetSha, reused: installed.reused, restarted }, pc.yellow(`Updated unreleased git payload ${manifest.sha.slice(0, 12)} → ${targetSha.slice(0, 12)} from ${manifest.repo}@${manifest.ref}${restarted ? " and restarted the active service" : ""}.`));
    return;
  }
  const targetVersion = await resolvePublishedVersion(request.spec, runCommand);
  const currentVersion = manifest?.version ?? (mode === "global-npm" ? packageVersion : undefined);
  const comparison = currentVersion ? compareVersions(targetVersion, currentVersion) : 1;
  if (options.check) { emit(options, { mode, currentVersion: currentVersion ?? null, targetVersion, updateAvailable: comparison > 0, downgrade: comparison < 0, channel: request.channel }, comparison > 0 ? `Update available: ${targetVersion}` : comparison < 0 ? `Target ${targetVersion} is older than ${currentVersion}.` : `paperclipai ${targetVersion} is current.`); if (comparison > 0) process.exitCode = 10; return; }
  if (mode === "global-npm") {
    if (comparison < 0 && options.yes !== true) { const confirmed = await (overrides.confirm ?? defaultConfirm)(`Downgrade paperclipai from ${currentVersion} to ${targetVersion}?`); if (!confirmed) throw new Error("Downgrade cancelled. Re-run with --yes to confirm explicitly."); }
    const args = ["install", "-g", `paperclipai@${targetVersion}`, `--registry=${PUBLIC_NPM_REGISTRY}`, `--@paperclipai:registry=${PUBLIC_NPM_REGISTRY}`]; console.log(`Running: npm ${args.join(" ")}`);
    if (!options.dryRun) {
      const npmConfigDir = fs.mkdtempSync(path.join(os.tmpdir(), "paperclip-npm-"));
      const npmUserConfigPath = path.join(npmConfigDir, "npmrc");
      try {
        fs.writeFileSync(npmUserConfigPath, `registry=${PUBLIC_NPM_REGISTRY}\n@paperclipai:registry=${PUBLIC_NPM_REGISTRY}\n`, { mode: 0o600 });
        await runCommand("npm", args, {
          env: {
            ...process.env,
            npm_config_registry: PUBLIC_NPM_REGISTRY,
            NPM_CONFIG_REGISTRY: PUBLIC_NPM_REGISTRY,
            npm_config_userconfig: npmUserConfigPath,
            NPM_CONFIG_USERCONFIG: npmUserConfigPath,
          },
          maxBuffer: 16 * 1024 * 1024,
        });
      } finally {
        fs.rmSync(npmConfigDir, { recursive: true, force: true });

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Confirm explicitly: `paperclipai update --version <older> --yes`.
  2. Accept the prompt interactively (y/Enter) when in a TTY.
  3. Double-check the target version is what you intend if the downgrade is unintentional.

Example fix

# before
paperclipai update --version 1.0.0
# after
paperclipai update --version 1.0.0 --yes
Defensive patterns

Strategy: validation

Validate before calling

// Decide downgrade consent up front for global-npm
import { compareVersions } from '../commands/update.js';
function shouldAutoConfirmDowngrade(current: string, target: string, yes?: boolean): boolean {
  return compareVersions(target, current) < 0 ? Boolean(yes) : true;
}
// options.yes = shouldAutoConfirmDowngrade(currentVersion, targetVersion, options.yes);

Try / catch

try {
  await updateCommand(options);
} catch (error) {
  if (error instanceof Error && error.message === 'Downgrade cancelled. Re-run with --yes to confirm explicitly.') {
    // respect the user's cancellation; only retry once they pass --yes
    throw error;
  } else throw error;
}

Prevention

When it happens

Trigger: Global-npm install mode, `paperclipai update --version <older>` (or a canary/latest resolution that points backward), user declines the 'Downgrade paperclipai from X to Y?' prompt. Also auto-thrown in non-TTY contexts where defaultConfirm returns false unless --yes is passed.

Common situations: Pinning to an older release to dodge a regression, run from a pipe/CI without --yes. Typing a wrong (older) version number. Canary channel resolving to an older build.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/202cd22a2cf18e48. Report an issue: GitHub.