diff --git a/lib/pregate/index.ts b/lib/pregate/index.ts index a8e0f7298..12413fced 100644 --- a/lib/pregate/index.ts +++ b/lib/pregate/index.ts @@ -257,14 +257,14 @@ export function clearDecision(file: PregateFile, lane: string, input: ClearInput return { receipt: `attested:${input.runUrl}`, attested: true }; } if (input.runUrl && input.evidence) { - const invalid = (why: string): ClearDecision => ({ refused: 'PREGATE_RECEIPT_INVALID', message: `REUSE: refused reason=${why}; ${lane} stays uncleared` }); + const invalid = (why: string): ClearDecision => ({ refused: 'PREGATE_RECEIPT_INVALID', message: `REUSE: refused reason=${why}; ${lane} stays uncleared`, fix: `clear ${lane} with a run of its own workflow: gh workflow run ${target.workflow} --ref , then gstack-pregate clear --remote ${lane} --run-url ` }); const id = parseRunRef(input.runUrl, input.evidence.repo); if (id === null) return invalid(`run_ref_invalid — ${JSON.stringify(input.runUrl)} is not a run id or a run URL on ${input.evidence.repo}`); - let run: ApiRun; + let run: ApiRun | null; try { run = input.evidence.deps.run(id); } catch (e: any) { return invalid(`api_error — reading run ${id} failed: ${String(e?.message ?? e).slice(0, 300)}`); } const want = `.github/workflows/${target.workflow}`; - if (run.path !== want) return invalid(`workflow_mismatch — run ${id} attempt ${run.run_attempt} ran ${run.path ?? 'an unknown workflow'}, not ${want}`); + if (run?.path !== want) return invalid(`workflow_mismatch — run ${id} attempt ${run?.run_attempt ?? '?'} ran ${run?.path ?? 'an unknown workflow'}, not ${want}`); } const receipt = input.runUrl ?? (input.bundleLane ? `bundle-lane:${input.bundleLane}` : undefined); if (!receipt) return { refused: 'usage', message: `${lane} clears with --run-url or --bundle-lane