jackwener/OpenCLI · warning · CommandExecutionError
Clip ${clipId} status is "${clip.status}" — not complete yet
Error message
Clip ${clipId} status is "${clip.status}" — not complete yet. Retry once generation finishes. What it means
Thrown by `opencli suno download` when the clip was found but its `status` is anything other than 'complete'. Suno clips go through queued/submitting/running states during generation; only complete clips have downloadable audio. The error surfaces the actual status so you know to wait.
Source
Thrown at clis/suno/download.js:115
});
if (!res.ok) return { ok: false, error: 'HTTP ' + res.status };
const payload = await res.json().catch(() => null);
if (!payload || !Array.isArray(payload.clips)) return { ok: false, error: 'malformed clips payload' };
return { ok: true, clips: payload.clips };
})()`));
if (!feedRes?.ok) {
throw new CommandExecutionError(`Suno feed lookup failed: ${feedRes?.error || 'unknown'}`);
}
if (!Array.isArray(feedRes.clips)) {
throw new CommandExecutionError('Suno feed lookup returned malformed clips payload');
}
const clip = feedRes.clips.find(c => c.id === clipId);
if (!clip) {
throw new EmptyResultError('suno download', `Clip ${clipId} not found in your account. Confirm at ${SUNO_URL}/song/${clipId}.`);
}
if (clip.status !== 'complete') {
throw new CommandExecutionError(`Clip ${clipId} status is "${clip.status}" — not complete yet. Retry once generation finishes.`);
}
const result = await downloadSunoClip(page, clip, outputDir, formats, deviceId);
if (!result.written.some(w => w.ok)) {
throw new CommandExecutionError(`Suno download wrote no files for clip ${clipId}`);
}
const link = `${SUNO_URL}/song/${clip.id}`;
const writtenSummary = result.written
.map(w => w.ok ? `${w.format}:${displayPath(w.file)}` : `${w.format}:✗(${w.reason})`)
.join(' | ');
const skippedSummary = skippedPaid.length
? ` | skipped(needs --confirm-paid):${skippedPaid.join(',')}`
: '';
const fileSummary = `${writtenSummary}${skippedSummary}`;
const anyFailed = result.written.some(w => !w.ok);
return [{
status: anyFailed ? '⚠ partial' : '✅ saved',View on GitHub (pinned to 49907e53dc)
Solutions
- Wait for generation to finish (typically 1–2 minutes) and retry the download command.
- If you control the script, poll the clip status or add a delay/sleep before downloading (generate already polls with --timeout when not using --sd).
- Check the clip at the printed suno.com/song/<id> link — if it is stuck in a non-complete state for a long time, generation failed; regenerate.
- Retry once; if the status never becomes complete, the clip errored server-side and cannot be downloaded.
Example fix
// before
const { clipIds } = await run('opencli suno generate "song" --sd true');
await run(`opencli suno download ${clipIds[0]}`); // too early
// after
const { clipIds } = await run('opencli suno generate "song" --sd true');
await sleep(120000); // or poll status until 'complete'
await run(`opencli suno download ${clipIds[0]}`); Defensive patterns
Strategy: retry
Validate before calling
// poll the clip page/API before downloading; only download when status is 'complete'
async function waitUntilComplete(clipId, { timeoutMs = 300000, intervalMs = 15000 } = {}) {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
const status = await getClipStatus(clipId); // e.g. via suno.com/song/<id>
if (status === 'complete') return;
if (['error', 'failed'].includes(status)) throw new Error('generation failed');
await new Promise(r => setTimeout(r, intervalMs));
}
throw new Error('timed out waiting for clip');
} Type guard
const isComplete = (clip) => clip?.status === 'complete';
Try / catch
for (let attempt = 0; attempt < 5; attempt++) {
try { await run(`opencli suno download ${clipId}`); break; }
catch (err) {
if (!String(err.message).includes('not complete yet')) throw err;
await new Promise(r => setTimeout(r, 30000)); // back off and retry
}
} Prevention
- Don't use --sd on generate if you plan to download immediately — plain generate already polls until complete.
- Add a 1–2 minute delay or status poll between generation and download in scripts.
- Treat long-stuck non-complete status as a failed generation and regenerate.
When it happens
Trigger: Running `opencli suno download <clip-id>` immediately after `suno generate` or from the web UI while Suno is still generating the song (status e.g. 'running', 'queued', 'submitting'), or when generation actually failed/stuck in a non-complete state.
Common situations: Scripting download right after generate without polling, using --sd on generate then downloading immediately, or a clip stuck due to a Suno-side generation failure.
Related errors
- Suno generation did not complete within ${timeoutSeconds}s.
- Midjourney job ${jobId} (last status: ${lastStatus})
- Suno feed API returned malformed JSON while polling clips
- Timeout waiting for Antigravity reply after ${timeout / 1000
- Waiting for Bilibili session cookies
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/4245f28fe9080def.
Report an issue: GitHub.