decolua/9router · error
Deployment failed: ${data.readyState}
Error message
Deployment failed: ${data.readyState} What it means
pollDeployment polls the Vercel v13 deployments API every 3 seconds waiting for readyState READY. When Vercel reports the deployment's readyState as ERROR or CANCELED, the function throws `Deployment failed: <state>` to abort the wait instead of returning a broken deployment. It means Vercel itself finished the build with a failure or someone/something canceled it.
Source
Thrown at src/app/api/proxy-pools/vercel-deploy/route.js:51
});
return new Response(response.body, {
status: response.status,
headers: response.headers,
});
}
`;
async function pollDeployment(deploymentId, token, maxMs = 120000) {
const start = Date.now();
while (Date.now() - start < maxMs) {
const res = await fetch(`${VERCEL_API}/v13/deployments/${deploymentId}`, {
headers: { Authorization: `Bearer ${token}` },
});
const data = await res.json();
if (data.readyState === "READY") return data;
if (data.readyState === "ERROR" || data.readyState === "CANCELED") {
throw new Error(`Deployment failed: ${data.readyState}`);
}
await new Promise((r) => setTimeout(r, 3000));
}
throw new Error("Deployment timed out");
}
// POST /api/proxy-pools/vercel-deploy
export async function POST(request) {
try {
const body = await request.json();
const vercelToken = body.vercelToken;
const projectName = body.projectName?.trim() || `relay-${Date.now().toString(36)}`;
if (!vercelToken) {
return NextResponse.json({ error: "Vercel API token is required" }, { status: 400 });
}
// Deploy relay function to VercelView on GitHub (pinned to 90b52e06ff)
Solutions
- Check the deployment details via GET /v13/deployments/<id> (or the Vercel dashboard URL from the response) and inspect the build logs to see the actual build/runtime error.
- Retry the deploy once the underlying issue is fixed; the error is deterministic for a given payload, so fixing the deployment payload (files, projectSettings, target) is required, not a retry loop.
- Verify the Vercel token's team/scope matches the project and that the plan supports edge functions and the requested settings.
- If deployments are being CANCELED by concurrent deploys, serialize deployments (deploy one project at a time) or use unique project names.
Example fix
// before
if (data.readyState === "ERROR" || data.readyState === "CANCELED") {
throw new Error(`Deployment failed: ${data.readyState}`);
}
// after
if (data.readyState === "ERROR" || data.readyState === "CANCELED") {
const logsRes = await fetch(`${VERCEL_API}/v2/deployments/${deploymentId}/events?limit=20&builds=1`, { headers: { Authorization: `Bearer ${token}` } });
const events = await logsRes.json().catch(() => []);
const last = events.filter((e) => e.text).map((e) => e.text).slice(-5).join("\n");
throw new Error(`Deployment failed: ${data.readyState}${last ? `\n${last}` : ""}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check token scope/validity before deploying
const res = await fetch("https://api.vercel.com/v2/user", { headers: { Authorization: `Bearer ${token}` } });
if (!res.ok) throw new Error("Invalid Vercel token — fix before deploying"); Type guard
function isFailedDeployment(d) {
return d && (d.readyState === "ERROR" || d.readyState === "CANCELED");
} Try / catch
try {
const ready = await deployAndPoll(body);
} catch (err) {
if (/^Deployment failed: (ERROR|CANCELED)$/.test(err.message)) {
// surface Vercel dashboard/logs link to the user; do not retry blindly
} else {
throw err;
}
} Prevention
- Fetch and show deployment build logs (GET /v13/deployments/<id>/events) instead of only the state string
- Test the relay payload on a throwaway project before production deploys
- Serialize deployments per project to avoid CANCELED-by-supersede
- Validate the Vercel token and plan capabilities before creating the deployment
When it happens
Trigger: The POST /api/proxy-pools/vercel-deploy create-deployment call succeeds (202) but the resulting relay deployment later transitions to readyState ERROR (build/runtime failure of the generated api/relay.js edge function, invalid projectSettings, region/plan restrictions) or CANCELED (superseded by a newer deployment, manual cancel, or account-level cancellation).
Common situations: Edge runtime code rejected by Vercel (unsupported API in the bundled relay handler), a Vercel project with build checks/protected deployment policies, deploying on a plan that disallows the requested configuration, or a subsequent deploy of the same project canceling this one.
Related errors
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/3008e8533ada0bdf.
Report an issue: GitHub.