{"record":{"id":"e4886cd2b0a8f348","repo":"jackwener/OpenCLI","slug":"suno-feed-api-failed-while-polling-clips-http-r","errorCode":null,"errorMessage":"Suno feed API failed while polling clips (HTTP ${result.status || '?'})","messagePattern":"Suno feed API failed while polling clips \\(HTTP (.+?)\\)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/suno/utils.js","lineNumber":378,"sourceCode":"        const result = unwrapEvaluateResult(await page.evaluate(`(async () => {\n            const res = await fetch('${STUDIO_API}/api/feed/v3', {\n                method: 'POST',\n                headers: ${sunoHeadersJs(deviceId, { 'Content-Type': 'application/json' })},\n                body: JSON.stringify({ clip_ids: ${idsJson} }),\n            });\n            const body = await res.json().catch(() => null);\n            return { status: res.status, body };\n        })()`));\n\n        if (!result) {\n            await page.wait(pollSeconds);\n            continue;\n        }\n        if (result.status === 401 || result.status === 403) {\n            throw new AuthRequiredError(SUNO_DOMAIN, `Suno feed API rejected (HTTP ${result.status}). Re-login.`);\n        }\n        if (result.status < 200 || result.status >= 300) {\n            throw new CommandExecutionError(`Suno feed API failed while polling clips (HTTP ${result.status || '?'})`);\n        }\n        if (!result.body || typeof result.body !== 'object' || Array.isArray(result.body)) {\n            throw new CommandExecutionError('Suno feed API returned malformed JSON while polling clips');\n        }\n\n        const allClips = result.body.clips || [];\n        if (!Array.isArray(allClips)) {\n            throw new CommandExecutionError('Suno feed API returned malformed clips payload');\n        }\n        const ourClips = allClips.filter(c => targetSet.has(c.id));\n        const finished = ourClips.filter(c => c.status === 'complete' || c.status === 'error');\n\n        if (typeof onProgress === 'function') {\n            onProgress({ total: clipIds.length, done: finished.length, statuses: ourClips.map(c => `${c.id.slice(0,8)}:${c.status}`) });\n        }\n\n        if (finished.length === clipIds.length) return ourClips;\n        await page.wait(pollSeconds);","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/suno/utils.js#L360-L396","documentation":"pollSunoClips throws this CommandExecutionError when /api/feed/v3 returns any non-2xx, non-401/403 HTTP status (e.g. 429, 5xx). The `|| '?'` fallback covers a missing status from a null-ish evaluate result.","triggerScenarios":"The feed polling request gets a 429 rate-limit, 500/502/503 server error, or any other unexpected status outside 200-299 while waiting for clips to finish.","commonSituations":"Polling too aggressively (small pollSeconds) triggering Suno rate limits; Suno incident/outage causing 5xx responses; network proxy intercepting requests; heavy load during peak generation times.","solutions":["Retry the command after a short wait — most 5xx/429 are transient.","Increase pollSeconds (e.g. from 5 to 10-15) to reduce request rate.","Check Suno status/Discord for ongoing outages if 5xx persists.","Add retry-with-backoff around pollSunoClips for intermittent 429/5xx."],"exampleFix":"// before\nawait pollSunoClips(page, ids, 300, deviceId, 3);\n// after: slower polling to avoid rate limits\nawait pollSunoClips(page, ids, 300, deviceId, 10);","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const clips = await pollSunoClips(page, ids, timeout, deviceId, 10);\n} catch (e) {\n  if (e instanceof CommandExecutionError && /HTTP \\d+/.test(e.message)) {\n    // transient 429/5xx: back off and retry\n    await sleep(15000);\n    return pollSunoClips(page, ids, timeout, deviceId, 15);\n  }\n  throw e;\n}","preventionTips":["Use a poll interval of 10s or more to avoid rate limits","Wrap polling in retry-with-exponential-backoff","Watch Suno status channels during outages"],"tags":["network","http-error","suno","rate-limit"],"backgroundTag":"http-5xx-error","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}