{"record":{"id":"5367d9477a732e93","repo":"decolua/9router","slug":"deployment-timed-out","errorCode":null,"errorMessage":"Deployment timed out","messagePattern":"Deployment timed out","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/app/api/proxy-pools/vercel-deploy/route.js","lineNumber":55,"sourceCode":"    headers: response.headers,\n  });\n}\n`;\n\nasync function pollDeployment(deploymentId, token, maxMs = 120000) {\n  const start = Date.now();\n  while (Date.now() - start < maxMs) {\n    const res = await fetch(`${VERCEL_API}/v13/deployments/${deploymentId}`, {\n      headers: { Authorization: `Bearer ${token}` },\n    });\n    const data = await res.json();\n    if (data.readyState === \"READY\") return data;\n    if (data.readyState === \"ERROR\" || data.readyState === \"CANCELED\") {\n      throw new Error(`Deployment failed: ${data.readyState}`);\n    }\n    await new Promise((r) => setTimeout(r, 3000));\n  }\n  throw new Error(\"Deployment timed out\");\n}\n\n// POST /api/proxy-pools/vercel-deploy\nexport async function POST(request) {\n  try {\n    const body = await request.json();\n    const vercelToken = body.vercelToken;\n    const projectName = body.projectName?.trim() || `relay-${Date.now().toString(36)}`;\n\n    if (!vercelToken) {\n      return NextResponse.json({ error: \"Vercel API token is required\" }, { status: 400 });\n    }\n\n    // Deploy relay function to Vercel\n    const deployRes = await fetch(`${VERCEL_API}/v13/deployments`, {\n      method: \"POST\",\n      headers: {\n        Authorization: `Bearer ${vercelToken}`,","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/app/api/proxy-pools/vercel-deploy/route.js#L37-L73","documentation":"pollDeployment gives up after maxMs (default 120000 ms) if the deployment never reaches READY, ERROR, or CANCELED, throwing `Deployment timed out`. This is a client-side deadline, not a Vercel-reported failure — the deployment may still be building. The polling loop sleeps 3s between GET /v13/deployments/<id> calls and stops when the clock runs out.","triggerScenarios":"A deployment takes longer than 2 minutes to reach READY (slow build, build queue congestion on free plans, large project, or Vercel platform delays), so the while (Date.now() - start < maxMs) loop exits before readyState changes.","commonSituations":"Free/Hobby plan build queues during peak times, deployments stuck in QUEUED/INITIALIZING state, slow cold builds, or network slowness making each poll take longer so fewer polls fit in the window.","solutions":["Increase the maxMs deadline when calling pollDeployment (e.g. pollDeployment(deploymentId, vercelToken, 300000) for 5 minutes).","Check the deployment status manually in the Vercel dashboard or via GET /v13/deployments/<id> — if it eventually becomes READY, the relay URL (https://<url>) is usable even though this call threw.","Retry the POST; a fresh deployment often builds faster once the queue clears.","Reduce build time: the relay project is minimal, so long builds usually indicate Vercel-side queueing — retry at a different time or upgrade the plan for priority builds."],"exampleFix":"// before\nconst ready = await pollDeployment(deploymentId, vercelToken);\n// after\nconst ready = await pollDeployment(deploymentId, vercelToken, 300000); // 5 min","handlingStrategy":"retry","validationCode":"// No pre-call validation possible; choose a deadline proportional to plan/queue\nconst maxMs = process.env.VERCEL_DEPLOY_TIMEOUT_MS ? Number(process.env.VERCEL_DEPLOY_TIMEOUT_MS) : 300000;","typeGuard":null,"tryCatchPattern":"try {\n  const ready = await pollDeployment(id, token, 300000);\n} catch (err) {\n  if (err.message === \"Deployment timed out\") {\n    // Check status out-of-band; the deployment may still complete\n    const final = await fetch(`${VERCEL_API}/v13/deployments/${id}`, { headers: { Authorization: `Bearer ${token}` } }).then(r => r.json());\n    if (final.readyState === \"READY\") return final; // recover late build\n  }\n  throw err;\n}","preventionTips":["Set a generous timeout (3-5 min) instead of the 120s default","On timeout, poll once more out-of-band before declaring failure — builds often finish late","Surface the deployment id/URL so users can monitor progress in the Vercel dashboard","Avoid deploying during known Hobby-plan queue peaks or upgrade for priority builds"],"tags":["vercel","timeout","polling"],"backgroundTag":"poll-timeout","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}