jackwener/OpenCLI · error · EmptyResultError

Submission accepted but Suno returned no clip ids. Raw: ${JS

Error message

Submission accepted but Suno returned no clip ids. Raw: ${JSON.stringify(result.body).slice(0, 300)}

What it means

After a 2xx generate response with a valid JSON object, submitSunoGeneration requires a non-empty clips array to extract clip ids. If the object has no clips (or an empty array), EmptyResultError is thrown with a 300-char dump of the raw body for debugging.

Source

Thrown at clis/suno/utils.js:345

    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;
    const targetSet = new Set(clipIds);
    const idsJson = JSON.stringify(clipIds);

    while (Date.now() < deadline) {
        const result = unwrapEvaluateResult(await page.evaluate(`(async () => {
            const res = await fetch('${STUDIO_API}/api/feed/v3', {
                method: 'POST',
                headers: ${sunoHeadersJs(deviceId, { 'Content-Type': 'application/json' })},

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect the Raw JSON in the error message to see what Suno actually returned.
  2. Rephrase the prompt/lyrics — content moderation often accepts the request but returns no clips.
  3. Check credits/subscription status on suno.com and retry.
  4. Verify clip ids are read from the right field; update the CLI if Suno renamed the clips field.

Example fix

// before
const clips = result.body?.clips || [];
if (!clips.length) throw new EmptyResultError('suno generate', ...);
// after: log full body for diagnosis and check alternate fields
const clips = result.body?.clips || result.body?.data?.clips || [];
if (!clips.length) {
  console.error('Suno body:', JSON.stringify(result.body).slice(0, 500));
  throw new EmptyResultError('suno generate', 'no clips returned');
}
Defensive patterns

Strategy: validation

Validate before calling

// after submit, validate clips before consuming
if (!body?.clips || !body.clips.length) {
  console.error('Suno returned:', JSON.stringify(body).slice(0, 300));
}

Type guard

function hasClips(body) {
  return Array.isArray(body?.clips) && body.clips.length > 0;
}

Try / catch

try {
  const body = await submitSunoGeneration(page, payload);
} catch (e) {
  if (e instanceof EmptyResultError) {
    // inspect e.message raw dump; retry with adjusted prompt (moderation often causes empty clips)
  } else throw e;
}

Prevention

When it happens

Trigger: Suno accepted the generation POST (2xx) but the returned body.clips is missing or empty — e.g. the request was silently filtered (flagged prompt/lyrics), quota/throttling accepted the job but returned no clips, or the API envelope changed.

Common situations: Prompts that trigger Suno's content moderation get accepted but return zero clips; account with exhausted credits edge-cases; Suno A/B testing a new response schema; submitting with malformed style fields the server ignores.

Related errors


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