paperclipai/paperclip · error · Error

Expected plan, plan-migrator, pack, publish, publish-image…

Error message

Expected plan, plan-migrator, pack, publish, publish-image, or result.

What it means

The preview-artifacts CLI accepts exactly one subcommand: plan, plan-migrator, pack, publish, publish-image, or result. Any other (or missing) first argument reaches the else branch and throws this usage error; the catch handler prints it and sets exit code 1.

Solutions

  1. Pass one of the supported subcommands: plan, plan-migrator, pack, publish, publish-image, or result.
  2. Check the workflow YAML for typos in the command argument and its argument order.
  3. Run the script with no args or read the source header to see the usage before invoking.
  4. Fix any shell quoting issues that could inject an empty first argument.

Example fix

// before
node scripts/preview-artifacts.mjs deploy <sha> <requestId>
// after
node scripts/preview-artifacts.mjs publish <sha> <requestId>
Defensive patterns

Strategy: validation

Validate before calling

const COMMANDS = ['plan','plan-migrator','pack','publish','publish-image','result'];
if (!COMMANDS.includes(process.argv[2])) {
  throw new Error(`Unknown command ${process.argv[2]}; expected one of ${COMMANDS.join(', ')}`);
}

Type guard

const isPreviewCommand = (c) => ['plan','plan-migrator','pack','publish','publish-image','result'].includes(c);

Try / catch

try {
  await runPreviewCommand(command, args);
} catch (e) {
  if (String(e.message).startsWith('Expected plan')) {
    console.error('Usage: preview-artifacts.mjs <plan|plan-migrator|pack|publish|publish-image|result> [args]');
    process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: Invoking `node scripts/preview-artifacts.mjs` with no subcommand, a typo'd subcommand (e.g. 'pubish', 'build'), or extra/misspelled arguments that shift parsing.

Common situations: Hand-running the script locally with the wrong verb; a GitHub Actions step passing the wrong command name; renaming a step in the workflow without updating the command argument.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/3d35794b1e54350b. Report an issue: GitHub.

Appendix: source

Thrown at scripts/preview-artifacts.mjs:220

    if (command === "plan" || command === "plan-migrator") {
      const [sha, requestId, migrator] = args;
      validateRequest(sha, requestId);
      if (process.env.GITHUB_REF !== "refs/heads/master") throw new Error("Preview workflow definitions must run from master.");
      const { image, packages } = await planArtifacts(sha, {
        image: command === "plan", migrator: command === "plan-migrator" || migrator === "true",
      });
      appendFileSync(process.env.GITHUB_OUTPUT, `image=${image}\npackages=${packages}\n`);
    } else if (command === "pack") packPreview(...args);
    else if (command === "publish") await publishPreview(...args);
    else if (command === "publish-image") await publishImage(...args);
    else if (command === "result") {
      const [sha, requestId] = args;
      validateRequest(sha, requestId);
      if (!await imageExists(sha)) throw new Error("Cloud image is still missing.");
      if (process.env.PREVIEW_MIGRATOR === "true" && !(await packageExists("@paperclipai/shared", sha) && await packageExists("@paperclipai/db", sha))) throw new Error("Preview packages are still missing.");
      mkdirSync("stack-deploy-result", { recursive: true });
      writeFileSync("stack-deploy-result/result.json", JSON.stringify({ version: 1, stage: "build", requestId, sha, status: "ready" }) + "\n");
    } else throw new Error("Expected plan, plan-migrator, pack, publish, publish-image, or result.");
  } catch (error) { console.error(error.message); process.exitCode = 1; }
}

View on GitHub (pinned to 3f1d897a7c)