{"record":{"id":"6896739d15d829d6","repo":"paperclipai/paperclip","slug":"cloud-source-verification-timed-out-for-sha-rerun-cloud","errorCode":null,"errorMessage":"Cloud source verification timed out for ${sha}. Rerun Cloud readiness before retrying the release.","messagePattern":"Cloud source verification timed out for (.+?)\\. Rerun Cloud readiness before retrying the release\\.","errorType":"console","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/cloud-source-verification.mjs","lineNumber":151,"sourceCode":"      await pause(response);\n    }\n  };\n}\n\nexport async function waitForSourceVerification(sha, {\n  api, now = Date.now, sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),\n  timeoutMs = 45 * 60_000, intervalMs = 30_000, log = console.log,\n} = {}) {\n  assertSha(sha);\n  const deadline = now() + timeoutMs;\n  log(`Waiting for ${sourceVerificationJob} for ${sha}.`);\n  while (now() < deadline) {\n    const result = await readSourceVerification(sha, api);\n    if (result) return result;\n    const remaining = deadline - now();\n    if (remaining > 0) await sleep(Math.min(intervalMs, remaining));\n  }\n  throw new Error(`Cloud source verification timed out for ${sha}. Rerun Cloud readiness before retrying the release.`);\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n  try {\n    if (!process.env.GITHUB_TOKEN) throw new Error(\"GITHUB_TOKEN with Actions read access is required.\");\n    // One deadline for both layers: the reader stops retrying when the poll it\n    // serves is out of time, instead of extending the wait past its timeout.\n    const timeoutMs = 45 * 60_000;\n    const deadline = Date.now() + timeoutMs;\n    const api = createActionsReader({ token: process.env.GITHUB_TOKEN, deadlineAt: () => deadline });\n    const proof = await waitForSourceVerification(process.argv[2], { api, timeoutMs });\n    const message = `Source verification passed for ${proof.sha}: https://github.com/${repository}/actions/runs/${proof.runId}/attempts/${proof.attempt} (job ${proof.jobId}).`;\n    console.log(message);\n    if (process.env.GITHUB_STEP_SUMMARY) await appendFile(process.env.GITHUB_STEP_SUMMARY, `${message}\\n`);\n  } catch (error) {\n    console.error(error.message);\n    process.exitCode = 1;\n  }","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/scripts/cloud-source-verification.mjs#L133-L169","documentation":"waitForSourceVerification polls readSourceVerification every 30s for up to 45 minutes (default timeoutMs). If the Cloud source verified v1 job has not completed successfully for the sha by the deadline — without ever observing a completed non-success verdict — it throws this timeout. Callers are told to rerun Cloud readiness before retrying the release.","triggerScenarios":"The push-triggered Cloud readiness run for the sha is queued/running longer than 45 minutes; no matching run exists at all for the sha (returns undefined every poll); a rerun keeps the attempt in progress past the deadline; workflow waits on required approvals/environments.","commonSituations":"GitHub Actions congestion delaying job start; the workflow run stuck on a pending environment approval; sha pushed but workflow disabled (cloud-readiness.yml on a branch where Actions is off) so no run ever starts; typo'd/not-full sha so the head_sha filter never matches.","solutions":["Confirm a push run exists for the sha on master: https://github.com/paperclipai/paperclip/actions/workflows/cloud-readiness.yml, filtered by the commit.","Rerun Cloud readiness (workflow_dispatch or re-run) and then retry the release poll for a fresh 45-minute window.","Check whether the run is stuck on an environment/branch-protection approval and approve it.","If runs legitimately take longer than 45 minutes, raise timeoutMs passed to waitForSourceVerification.","Verify the sha passed as argv[2] is the full 40-char lowercase commit sha."],"exampleFix":"// before: default 45-minute wait\nconst proof = await waitForSourceVerification(sha, { api, timeoutMs });\n// after: allow slow CI\nconst proof = await waitForSourceVerification(sha, { api, timeoutMs: 90 * 60_000 });","handlingStrategy":"try-catch","validationCode":"// before polling: confirm a run even exists for the sha\nconst wf = await api('/repos/paperclipai/paperclip/actions/workflows/cloud-readiness.yml');\nconst runs = await api(`/repos/paperclipai/paperclip/actions/workflows/${wf.id}/runs?head_sha=${sha}&event=push&branch=master&per_page=1`);\nif (runs.total_count === 0) throw new Error('No Cloud readiness push run for this sha yet — push or trigger one first');","typeGuard":null,"tryCatchPattern":"try {\n  const proof = await waitForSourceVerification(sha, { api, timeoutMs });\n} catch (e) {\n  if (e.message.startsWith('Cloud source verification timed out')) {\n    console.error('Not verified within the window — rerun Cloud readiness, then retry the release.');\n  }\n}","preventionTips":["Trigger Cloud readiness immediately after pushing the sha so the 45-minute window is not wasted waiting in queue.","Approve environment/branch-protection gates promptly; approvals pause the clock invisibly to the poller.","Pass the full 40-char lowercase sha — partial or uppercase shas never match head_sha.","Raise timeoutMs for releases during known GitHub congestion."],"tags":["timeout","github-actions","ci","release-gate"],"backgroundTag":"request-timeout","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"}