jackwener/OpenCLI · error · CommandExecutionError
Suno generation returned malformed clip identity.
Error message
Suno generation returned malformed clip identity.
What it means
The CLI maps submission.clips to their ids and throws if any clip is missing an id. Suno returned clip objects but at least one lacks a usable identity, so polling/downloading that clip would be impossible.
Source
Thrown at clis/suno/generate.js:174
lyrics,
tags,
negativeTags,
description,
makeInstrumental,
weirdness,
styleWeight,
userTier: session.planId,
createSessionToken,
transactionUuid,
deviceId,
});
if (!Array.isArray(submission.clips)) {
throw new CommandExecutionError('Suno generation returned malformed clips payload.');
}
const clipIds = submission.clips.map(c => c?.id);
if (clipIds.some(id => !id)) {
throw new CommandExecutionError('Suno generation returned malformed clip identity.');
}
if (!clipIds.length) {
throw new CommandExecutionError('Suno accepted the request but returned no clip ids.');
}
const clips = await pollSunoClips(page, clipIds, timeout, deviceId);
const completed = clips.filter(c => c.status === 'complete');
if (!completed.length) {
const errors = clips.map(c => `${c.id.slice(0, 8)}:${c.status}`).join(', ');
throw new CommandExecutionError(`All Suno clips failed (${errors}). Open ${SUNO_URL}/song/${clipIds[0]} to inspect.`);
}
const rows = [];
for (const clip of clips) {
const link = `${SUNO_URL}/song/${clip.id}`;
if (clip.status !== 'complete') {
rows.push({
status: `❌ ${clip.status}`,View on GitHub (pinned to 49907e53dc)
Solutions
- Dump submission.clips to inspect the malformed entries and confirm the schema drift.
- Check whether Suno renamed the clip id field (e.g. id → clipId) and update the mapping.
- Retry the generation — a transient server glitch may have produced a partial payload.
- Filter out clips without ids as a workaround, if partial results are acceptable.
Example fix
// before const clipIds = submission.clips.map(c => c?.id); // after: tolerate partial entries const clipIds = submission.clips.map(c => c?.id).filter(Boolean);
Defensive patterns
Strategy: type-guard
Validate before calling
const clipIds = (submission.clips || []).map(c => c?.id).filter(id => typeof id === 'string' && id);
if (clipIds.length !== submission.clips.length) console.warn('some clips missing ids', submission.clips); Type guard
function isClipWithId(c) { return !!c && typeof c === 'object' && typeof c.id === 'string' && c.id.length > 0; } Try / catch
try {
const ids = submission.clips.map(c => { if (!isClipWithId(c)) throw new Error('clip without id'); return c.id; });
} catch (e) {
if (/without id/.test(e.message)) { dumpPayloadForDebugging(submission); }
throw e;
} Prevention
- Validate each clip object right after submission.
- Keep a recorded sample of a real Suno clips payload for regression checks.
- Filter-and-warn instead of hard-fail when partial results are acceptable.
- Watch for Suno field renames (id vs clipId) after site updates.
When it happens
Trigger: `submission.clips.map(c => c?.id)` yields at least one falsy id — a clip entry is null, undefined, or has no id field.
Common situations: Suno partially updated its clip object schema (id renamed/moved), or returned placeholder entries for clips that were rejected server-side.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Bilibili creator comparison returned a malformed manuscript
- Bilibili creator comparison API returned malformed list data
- Bilibili creator comparison returned duplicate rows for ${bv
- Flomo API returned a malformed memo entry
- Flomo API returned a memo without slug/id
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0851d170a53f5a4a.
Report an issue: GitHub.