{"record":{"id":"f080b4f62949f0ba","repo":"paperclipai/paperclip","slug":"cloud-source-verification-did-not-pass-for-sha-run-run-id","errorCode":null,"errorMessage":"Cloud source verification did not pass for ${sha} (run ${run.id}, attempt ${run.run_attempt}). Rerun Cloud readiness before retrying the release.","messagePattern":"Cloud source verification did not pass for (.+?) \\(run (.+?), attempt (.+?)\\)\\. Rerun Cloud readiness before retrying the release\\.","errorType":"console","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/cloud-source-verification.mjs","lineNumber":59,"sourceCode":"    const batch = await api(`/repos/${repository}/actions/runs/${run.id}/attempts/${run.run_attempt}/jobs?per_page=100&page=${page}`);\n    if (!Array.isArray(batch.jobs)) throw new Error(\"Cloud readiness job listing is malformed.\");\n    jobs.push(...batch.jobs);\n    if (batch.jobs.length < 100) break;\n    if (page === 10) throw new Error(\"Cloud readiness job listing is incomplete.\");\n  }\n  const matches = jobs.filter((job) => job.name === sourceVerificationJob);\n  if (matches.length > 1) throw new Error(\"Cloud source verification job is ambiguous.\");\n  const job = matches[0];\n  if (job?.status === \"completed\" && job.conclusion === \"success\" &&\n      job.head_sha === sha && job.run_id === run.id && job.run_attempt === run.run_attempt) {\n    // Re-read the run after its jobs: a rerun that started during polling must\n    // not let the previous attempt through. Changes are retried next poll.\n    const current = await api(`/repos/${repository}/actions/runs/${run.id}`);\n    if (!trustedRun(current, sha, workflow.id) || current.run_attempt !== run.run_attempt) return undefined;\n    return { sha, runId: run.id, attempt: run.run_attempt, jobId: job.id };\n  }\n  if (job?.status === \"completed\" || run.status === \"completed\") {\n    throw new Error(`Cloud source verification did not pass for ${sha} (run ${run.id}, attempt ${run.run_attempt}). Rerun Cloud readiness before retrying the release.`);\n  }\n  return undefined;\n}\n\n// Statuses that say \"ask again\", not \"the answer is no\". A release must not be\n// blocked because GitHub returned a gateway error during a 45-minute poll.\nconst TRANSIENT_READ_STATUSES = new Set([408, 425, 429, 500, 502, 503, 504]);\n\n// A rate-limited read also says \"ask again\", and GitHub reports both primary\n// and secondary rate limits as 403. Only the headers separate that from a\n// token that may not read Actions, which must still fail at once.\nfunction rateLimited(response) {\n  if (response.status !== 403) return false;\n  const header = (name) => response.headers?.get?.(name) ?? null;\n  return header(\"retry-after\") !== null || header(\"x-ratelimit-remaining\") === \"0\";\n}\n\n/** Milliseconds from a Retry-After header, when it carries a sane delay. */","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/scripts/cloud-source-verification.mjs#L41-L77","documentation":"When the selected run attempt finished (or the matched job completed) but not with conclusion 'success' for this sha/attempt, the script throws this definitive failure. Unlike timeouts (which return undefined and keep polling), a completed non-success run means the verification answer is 'no' and the release must not retry until Cloud readiness is rerun.","triggerScenarios":"The Cloud source verified v1 job completed with conclusion failure/cancelled/timed_out, or the run itself completed without a passing verification job; then the next readSourceVerification poll throws with the run id and attempt in the message.","commonSituations":"Cloud readiness failed on a lint/test step in CI; the workflow was cancelled; an earlier failed attempt is being observed after someone triggered a rerun but the old attempt completed first; a workflow edit removed or renamed the verification job so it never succeeds.","solutions":["Open the run link pattern https://github.com/paperclipai/paperclip/actions/runs/{runId}/attempts/{attempt} and read why the job failed (logs of 'Cloud source verified v1').","Fix the failing source check in the repo, push, and let a fresh push-triggered Cloud readiness run complete on the new sha.","Rerun Cloud readiness ('Re-run all jobs') so a new successful attempt exists for the same sha, then retry the release.","Confirm the job named 'Cloud source verified v1' still exists in the workflow; if renamed, restore the exact versioned name."],"exampleFix":"# before: skipping the failing check locally\ngit push origin HEAD\n# after: verify locally before pushing\npnpm -r typecheck && pnpm test:run && git push origin HEAD","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isPassing(job, sha, run) {\n  return job?.status === 'completed' && job?.conclusion === 'success' &&\n    job?.head_sha === sha && job?.run_id === run.id && job?.run_attempt === run.run_attempt;\n}","tryCatchPattern":"try {\n  const proof = await waitForSourceVerification(sha, { api, timeoutMs });\n} catch (e) {\n  if (/Cloud source verification did not pass/.test(e.message)) {\n    const [, runId, attempt] = e.message.match(/run (\\d+), attempt (\\d+)/) ?? [];\n    console.error(`Inspect https://github.com/paperclipai/paperclip/actions/runs/${runId}/attempts/${attempt}, fix, rerun Cloud readiness.`);\n  }\n}","preventionTips":["Run the same checks locally (pnpm -r typecheck && pnpm test:run) before pushing, so Cloud readiness passes on the first attempt.","Watch the Cloud readiness run after pushing; fix failures before starting the release poll.","Never cancel the workflow run for a sha you are about to release against.","Keep the 'Cloud source verified v1' job present and green on every push to master."],"tags":["github-actions","ci-failure","release-gate"],"backgroundTag":"http-error-response","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"}