{"record":{"id":"d2d7e4be9f514123","repo":"Hmbown/CodeWhale","slug":"no-successful-asset-publishing-job-found-in-release-yml","errorCode":null,"errorMessage":"No successful asset-publishing job found in release.yml workflow runs for ${tag} at ${tagSha}. Repair the Release workflow before publishing npm.","messagePattern":"No successful asset-publishing job found in release\\.yml workflow runs for (.+?) at (.+?)\\. Repair the Release workflow before publishing npm\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"npm/codewhale/scripts/verify-release-assets.js","lineNumber":252,"sourceCode":"    const releaseJob = (jobs.jobs || []).find(\n      (job) => job.name === \"release\" && job.conclusion === \"success\",\n    );\n    if (releaseJob) {\n      // #5429: pin asset freshness to the successful release job's own\n      // started_at, not the run-level run_started_at. A job-level rerun\n      // (`gh run rerun --failed`) bumps run_started_at past the asset upload\n      // timestamps even though this release job produced those assets.\n      return { ...candidate, release_job_started_at: releaseJob.started_at || null };\n    }\n  }\n\n  if (orderedCandidates.length === 0) {\n    throw new Error(\n      `No release.yml workflow run found for ${tag} at ${tagSha}. ` +\n        \"Rerun the Release workflow before publishing npm, or increase the verifier's last-100-runs search window.\",\n    );\n  }\n  throw new Error(\n    `No successful asset-publishing job found in release.yml workflow runs for ${tag} at ${tagSha}. ` +\n      \"Repair the Release workflow before publishing npm.\",\n  );\n}\n\nfunction parseGitHubTime(value, label) {\n  const timestamp = Date.parse(value);\n  if (!Number.isFinite(timestamp)) {\n    throw new Error(`GitHub ${label} timestamp is invalid: ${value}`);\n  }\n  return timestamp;\n}\n\nfunction assertReleaseAssetsFresh(release, expectedAssets, run) {\n  const assetsByName = new Map((release.assets || []).map((asset) => [asset.name, asset]));\n  const missing = expectedAssets.filter((asset) => !assetsByName.has(asset));\n  if (missing.length > 0) {\n    throw new Error(`GitHub Release is missing required release asset(s): ${missing.join(\", \")}`);","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/npm/codewhale/scripts/verify-release-assets.js#L234-L270","documentation":"When candidate release.yml runs exist for the tag/SHA but none contains a successful job that published assets, findReleaseWorkflowRun throws this error instructing you to repair the Release workflow before publishing npm.","triggerScenarios":"Runs matching the tag exist but every one has failed/skipped asset-publishing jobs, so no successful job baseline can be attached to the release assets.","commonSituations":"Release workflow failing on asset upload (permissions, artifact name changes); workflow marked failed due to an unrelated matrix job; concurrency cancellations killing the job.","solutions":["Open the failed run in GitHub Actions, fix the failing asset-publish job, and rerun the workflow.","Check for GITHUB_TOKEN permissions issues on the release job (contents: write).","Verify job/step names and job.step conclusions still match what the verifier treats as an asset-publishing job."],"exampleFix":"// .github/workflows/release.yml\n// before\npermissions: { contents: read }\n// after\npermissions: { contents: write }","handlingStrategy":"retry","validationCode":"const run = matchingRuns.find(r => r.conclusion === \"success\"); if (!run) throw new Error(\"Release run for tag is not successful; fix workflow before publishing\");","typeGuard":null,"tryCatchPattern":"try { await verifyReleaseAssets(); } catch (e) { if (e.message.includes(\"No successful asset-publishing job\")) { console.error(\"Inspect the release.yml run logs, repair, and rerun.\"); process.exit(1); } throw e; }","preventionTips":["Require green release.yml runs in CI before publish jobs","Grant the release job contents:write permissions","Watch for concurrency cancellations that kill asset upload jobs"],"tags":["github-actions","ci","release","workflow"],"backgroundTag":"empty-result-set","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}