paperclipai/paperclip · error · Error
Invalid migrator producer response.
Error message
Invalid migrator producer response.
What it means
After a successful HTTP response, migratorPublished() validates the GitHub workflow-runs payload shape: workflow_runs must be an array, total_count a safe non-negative integer, and on page 1 zero total_count must correspond to zero listed runs. Anything else throws this error. It guards against unexpected API response shapes.
Solutions
- Print the raw response body to see what actually came back (proxy HTML vs JSON).
- Bypass proxies/VPNs that inject 200 HTML responses and retry.
- Pin an explicit X-GitHub-Api-Version header and check for GitHub API changelog updates affecting the actions/workflows/runs endpoint.
- If using a test double for fetchImpl, make it return { total_count, workflow_runs } consistent with each other.
Example fix
// before
const body = await response.json(); // assumed valid
// after
const body = await response.json();
if (!Array.isArray(body.workflow_runs)) console.error("Unexpected body:", body); Defensive patterns
Strategy: type-guard
Validate before calling
const res = await fetch(url, opts);
const text = await res.text();
let body; try { body = JSON.parse(text); } catch { throw new Error("Non-JSON body (proxy?): " + text.slice(0, 120)); } Type guard
const looksLikeRunList = (b) => b && Array.isArray(b.workflow_runs) && Number.isSafeInteger(b.total_count) && b.total_count >= 0;
Try / catch
try {
await waitForCloudArtifacts(sha);
} catch (error) {
if (error.message === "Invalid migrator producer response.") {
console.error("GitHub returned an unexpected payload — check proxies/GitHub status.");
} else throw error;
} Prevention
- Bypass corporate proxies that rewrite 200 bodies
- Check githubstatus.com when this appears suddenly
- Keep mocked fetch fixtures shape-accurate in tests
When it happens
Trigger: GitHub returns 200 with a malformed/JSON body missing workflow_runs or total_count (e.g. an HTML error page behind a captive proxy, a changed API contract, or total_count===0 with runs listed or vice versa).
Common situations: Corporate proxies or API gateways rewriting responses; GitHub API preview/contract changes; intermediary auth portals returning 200 HTML; mocking layers returning incomplete fixtures.
Related errors
- Cloud readiness workflow identity does not match.
- CreateOS sandbox identity or state is invalid.
- GitHub Actions read failed
- GitHub Actions read failed
- GitHub webhook configuration is incomplete
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/2490586d9f1639df.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/cloud-readiness.mjs:24
import path from "node:path";
import { imageExists, versionFor } from "./preview-artifacts.mjs";
import { verifyPublished } from "./cloud-migrator-artifacts.mjs";
const repository = "paperclipai/paperclip";
const workflow = ".github/workflows/cloud-migrator-artifacts.yml";
export async function migratorPublished(sha, fetchImpl, token) {
let pending = false;
const failures = [];
for (let page = 1; page <= 10; page++) {
const response = await fetchImpl(`https://api.github.com/repos/${repository}/actions/workflows/cloud-migrator-artifacts.yml/runs?branch=master&head_sha=${sha}&per_page=100&page=${page}`, {
headers: { Accept: "application/vnd.github+json", ...(token ? { Authorization: `Bearer ${token}` } : {}) },
redirect: "error", signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(`Migrator producer lookup failed: HTTP ${response.status}`);
const body = await response.json();
if (!Array.isArray(body.workflow_runs) || !Number.isSafeInteger(body.total_count) || body.total_count < 0 ||
(page === 1 && (body.total_count === 0) !== (body.workflow_runs.length === 0))) throw new Error("Invalid migrator producer response.");
if (body.total_count === 0) return false;
for (const run of body.workflow_runs) {
if (run.head_sha !== sha || run.head_branch !== "master" || run.path !== workflow ||
run.head_repository?.id !== 1170821064 || run.head_repository.full_name !== repository ||
!["push", "workflow_dispatch"].includes(run.event)) throw new Error("Migrator producer identity mismatch.");
// Publication is immutable. A later failed manual run must not hide a
// successful exact-source publisher; the signed bundle is checked next.
if (run.status === "completed" && run.conclusion === "success") return true;
if (run.status !== "completed") pending = true;
else failures.push(`${run.id}: ${run.conclusion}`);
}
if (page * 100 >= body.total_count) {
if (pending) return false;
throw new Error(`Migrator producers failed: ${failures.join(", ")}.`);
}
}
throw new Error("Too many migrator producer runs to establish publication.");
}View on GitHub (pinned to 3f1d897a7c)