{"record":{"id":"eceb9c26cf471032","repo":"paperclipai/paperclip","slug":"preview-workflow-definitions-must-run-from-master","errorCode":null,"errorMessage":"Preview workflow definitions must run from master.","messagePattern":"Preview workflow definitions must run from master\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/preview-artifacts.mjs","lineNumber":205,"sourceCode":"    const checks = await Promise.all([...pending].map(async (name) => ({ name, visible: await packageExists(name, sha, fetchImpl) })));\n    for (const { name, visible } of checks) {\n      if (visible) {\n        pending.delete(name);\n        console.log(`Visible ${name}@${versionFor(sha)}`);\n      }\n    }\n    if (pending.size) await sleep(10_000);\n  }\n  if (pending.size) throw new Error(`npm accepted the preview but it is not yet visible: ${[...pending].join(\", \")}. Retry reuses published packages.`);\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n  const [command, ...args] = process.argv.slice(2);\n  try {\n    if (command === \"plan\" || command === \"plan-migrator\") {\n      const [sha, requestId, migrator] = args;\n      validateRequest(sha, requestId);\n      if (process.env.GITHUB_REF !== \"refs/heads/master\") throw new Error(\"Preview workflow definitions must run from master.\");\n      const { image, packages } = await planArtifacts(sha, {\n        image: command === \"plan\", migrator: command === \"plan-migrator\" || migrator === \"true\",\n      });\n      appendFileSync(process.env.GITHUB_OUTPUT, `image=${image}\\npackages=${packages}\\n`);\n    } else if (command === \"pack\") packPreview(...args);\n    else if (command === \"publish\") await publishPreview(...args);\n    else if (command === \"publish-image\") await publishImage(...args);\n    else if (command === \"result\") {\n      const [sha, requestId] = args;\n      validateRequest(sha, requestId);\n      if (!await imageExists(sha)) throw new Error(\"Cloud image is still missing.\");\n      if (process.env.PREVIEW_MIGRATOR === \"true\" && !(await packageExists(\"@paperclipai/shared\", sha) && await packageExists(\"@paperclipai/db\", sha))) throw new Error(\"Preview packages are still missing.\");\n      mkdirSync(\"stack-deploy-result\", { recursive: true });\n      writeFileSync(\"stack-deploy-result/result.json\", JSON.stringify({ version: 1, stage: \"build\", requestId, sha, status: \"ready\" }) + \"\\n\");\n    } else throw new Error(\"Expected plan, plan-migrator, pack, publish, publish-image, or result.\");\n  } catch (error) { console.error(error.message); process.exitCode = 1; }\n}\n","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/scripts/preview-artifacts.mjs#L187-L223","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","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."],"exampleFix":"// before (fails on a branch)\non: push\n// after: restrict the plan job to master\non:\n  push:\n    branches: [master]","handlingStrategy":"validation","validationCode":"if (process.env.GITHUB_REF !== 'refs/heads/master') throw new Error('plan must run from master; ref=' + process.env.GITHUB_REF);","typeGuard":"const isMasterRun = () => process.env.GITHUB_REF === 'refs/heads/master';","tryCatchPattern":"try {\n  execSync('node scripts/preview-artifacts.mjs plan ...');\n} catch (e) {\n  if (String(e).includes('must run from master')) {\n    console.error('Re-trigger the preview workflow on master.');\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["ci","github-actions","branch-guard","preview"],"backgroundTag":"invalid-state-transition","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}