paperclipai/paperclip · error · Error
Preview workflow definitions must run from master.
Error message
Preview workflow definitions must run from master.
What it means
The 'plan' and 'plan-migrator' subcommands of the preview-artifacts script are only allowed to run on the master branch. When invoked in a GitHub Actions workflow whose GITHUB_REF is not 'refs/heads/master', the script throws this error to prevent computing preview artifact plans from non-canonical branches.
Solutions
- Trigger the preview workflow from the master branch (push or workflow_dispatch on master).
- If testing locally, set GITHUB_REF=refs/heads/master when invoking the script.
- Adjust the GitHub Actions trigger/branch filter so the plan job only runs on master.
- For local development outside CI, invoke the internal planArtifacts logic directly rather than the CLI gate.
Example fix
// before (fails on a branch)
on: push
// after: restrict the plan job to master
on:
push:
branches: [master] Defensive patterns
Strategy: validation
Validate before calling
if (process.env.GITHUB_REF !== 'refs/heads/master') throw new Error('plan must run from master; ref=' + process.env.GITHUB_REF); Type guard
const isMasterRun = () => process.env.GITHUB_REF === 'refs/heads/master';
Try / catch
try {
execSync('node scripts/preview-artifacts.mjs plan ...');
} catch (e) {
if (String(e).includes('must run from master')) {
console.error('Re-trigger the preview workflow on master.');
process.exit(1);
}
throw e;
} Prevention
- Configure the workflow's branch filter to master only for plan jobs.
- Avoid manual workflow_dispatch from feature branches for plan steps.
- For local testing, export GITHUB_REF=refs/heads/master explicitly.
- Keep plan computation out of PR-triggered pipelines.
When it happens
Trigger: Running `preview-artifacts.mjs plan <sha> <requestId>` (or plan-migrator) in a workflow triggered from a feature branch, pull request ref (e.g. refs/pull/123/merge), or tag so that process.env.GITHUB_REF differs from 'refs/heads/master'.
Common situations: Testing the preview workflow manually via workflow_dispatch on a branch; reusing the plan step in a fork or PR-triggered job; a workflow file with a wrong `runs-on` trigger branch configuration.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cloud artifacts timed out for
- Cloud source verification timed out for
- Preview packages are still missing.
- Cloud readiness job listing is incomplete.
- Cloud readiness job listing is malformed.
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/eceb9c26cf471032.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/preview-artifacts.mjs:205
const checks = await Promise.all([...pending].map(async (name) => ({ name, visible: await packageExists(name, sha, fetchImpl) })));
for (const { name, visible } of checks) {
if (visible) {
pending.delete(name);
console.log(`Visible ${name}@${versionFor(sha)}`);
}
}
if (pending.size) await sleep(10_000);
}
if (pending.size) throw new Error(`npm accepted the preview but it is not yet visible: ${[...pending].join(", ")}. Retry reuses published packages.`);
}
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
const [command, ...args] = process.argv.slice(2);
try {
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)