jackwener/OpenCLI · error · CommandExecutionError

Suno generate failed (HTTP ${status}): ${detail}

Error message

Suno generate failed (HTTP ${status}): ${detail}

What it means

For any generate API failure that isn't auth (401/403) or credits (402), submitSunoGeneration throws CommandExecutionError('Suno generate failed (HTTP <status>): <detail>') where detail is body.detail, the raw body, or a truncated JSON dump. It is the catch-all for rejected generation requests.

Source

Thrown at clis/suno/utils.js:337

            headers: ${sunoHeadersJs(deviceId, { 'Content-Type': 'application/json' })},
            body: ${JSON.stringify(bodyJson)},
        });
        const text = await res.text();
        let parsed = null;
        try { parsed = JSON.parse(text); } catch {}
        return { status: res.status, ok: res.ok, body: parsed, raw: parsed ? null : text.slice(0, 600) };
    })()`));

    if (!result || !result.ok) {
        const status = result?.status || 'unknown';
        const detail = result?.body?.detail || result?.raw || JSON.stringify(result?.body || {}).slice(0, 500);
        if (status === 401 || status === 403) {
            throw new AuthRequiredError(SUNO_DOMAIN, `Suno API rejected request (HTTP ${status}). Re-login on suno.com.`);
        }
        if (status === 402) {
            throw new CommandExecutionError(`Suno API: insufficient credits (HTTP 402). ${detail}`);
        }
        throw new CommandExecutionError(`Suno generate failed (HTTP ${status}): ${detail}`);
    }

    if (!result.body || typeof result.body !== 'object' || Array.isArray(result.body)) {
        throw new CommandExecutionError('Suno generate returned malformed JSON payload.');
    }
    const clips = result.body?.clips || [];
    if (!clips.length) {
        throw new EmptyResultError('suno generate', `Submission accepted but Suno returned no clip ids. Raw: ${JSON.stringify(result.body).slice(0, 300)}`);
    }
    return result.body;
}

// ─────────────────────────────────────────────────────────────────────────────
// Poll /api/feed/v3 (cookie auth, no Bearer).
// ─────────────────────────────────────────────────────────────────────────────

export async function pollSunoClips(page, clipIds, timeoutSeconds, deviceId, pollSeconds = 5, onProgress = null) {
    const deadline = Date.now() + timeoutSeconds * 1000;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the detail suffix — Suno usually includes a reason (policy violation, rate limit, validation error).
  2. For 429, wait and retry later; reduce generation frequency or batch size.
  3. For 400, adjust the prompt or parameters (model, slider values) to valid combinations.
  4. For 5xx, retry after a few minutes and check suno.com status — it's a server-side problem.
  5. Confirm your session is fresh (run a session/status check) to rule out borderline auth states surfaced as other codes.

Example fix

// before
opencli suno generate --prompt "..." --weirdness 0.9 --model chirp-fenix   // HTTP 400 invalid params
// after (use a valid parameter combination)
opencli suno generate --prompt "upbeat jazz" --model chirp-v4 --weirdness 0.5
Defensive patterns

Strategy: retry

Validate before calling

// Validate inputs before submission to avoid 400s
if (!prompt || typeof prompt !== 'string') throw new Error('prompt required');
if (!isSliderValue(weirdness) || !isSliderValue(styleWeight)) throw new Error('slider values must be 0..1');

Type guard

function isRetryableSunoFailure(err) {
  const m = /Suno generate failed \(HTTP (\d+)\)/.exec(err.message || '');
  return !!m && ['429','500','502','503','504'].includes(m[1]);
}

Try / catch

try {
  await submitSunoGeneration(page, params);
} catch (err) {
  if (isRetryableSunoFailure(err)) {
    await sleep(backoff); // retry 429/5xx with exponential backoff
  } else if (/HTTP 4\d\d/.test(err.message)) {
    console.error('Non-retryable request failure:', err.message); // fix params/prompt
  } else throw err;
}

Prevention

When it happens

Trigger: Suno returns 400 (invalid prompt/params, content-policy rejection), 429 (rate limit), 5xx (server error), or any other non-OK status from /api/generate/v2-web/ that doesn't match the auth/credit branches.

Common situations: Prompt violating Suno content policy (400); firing many generations back-to-back and hitting rate limits (429); Suno incident/server errors (5xx); invalid parameter combos (e.g. model incompatible with requested options).

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/d4b9bee51a7b972b. Report an issue: GitHub.