{"record":{"id":"0851d170a53f5a4a","repo":"jackwener/OpenCLI","slug":"suno-generation-returned-malformed-clip-identity","errorCode":null,"errorMessage":"Suno generation returned malformed clip identity.","messagePattern":"Suno generation returned malformed clip identity\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/suno/generate.js","lineNumber":174,"sourceCode":"            lyrics,\n            tags,\n            negativeTags,\n            description,\n            makeInstrumental,\n            weirdness,\n            styleWeight,\n            userTier: session.planId,\n            createSessionToken,\n            transactionUuid,\n            deviceId,\n        });\n\n        if (!Array.isArray(submission.clips)) {\n            throw new CommandExecutionError('Suno generation returned malformed clips payload.');\n        }\n        const clipIds = submission.clips.map(c => c?.id);\n        if (clipIds.some(id => !id)) {\n            throw new CommandExecutionError('Suno generation returned malformed clip identity.');\n        }\n        if (!clipIds.length) {\n            throw new CommandExecutionError('Suno accepted the request but returned no clip ids.');\n        }\n\n        const clips = await pollSunoClips(page, clipIds, timeout, deviceId);\n        const completed = clips.filter(c => c.status === 'complete');\n        if (!completed.length) {\n            const errors = clips.map(c => `${c.id.slice(0, 8)}:${c.status}`).join(', ');\n            throw new CommandExecutionError(`All Suno clips failed (${errors}). Open ${SUNO_URL}/song/${clipIds[0]} to inspect.`);\n        }\n\n        const rows = [];\n        for (const clip of clips) {\n            const link = `${SUNO_URL}/song/${clip.id}`;\n            if (clip.status !== 'complete') {\n                rows.push({\n                    status: `❌ ${clip.status}`,","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/suno/generate.js#L156-L192","documentation":"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.","triggerScenarios":"`submission.clips.map(c => c?.id)` yields at least one falsy id — a clip entry is null, undefined, or has no id field.","commonSituations":"Suno partially updated its clip object schema (id renamed/moved), or returned placeholder entries for clips that were rejected server-side.","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."],"exampleFix":"// before\nconst clipIds = submission.clips.map(c => c?.id);\n// after: tolerate partial entries\nconst clipIds = submission.clips.map(c => c?.id).filter(Boolean);","handlingStrategy":"type-guard","validationCode":"const clipIds = (submission.clips || []).map(c => c?.id).filter(id => typeof id === 'string' && id);\nif (clipIds.length !== submission.clips.length) console.warn('some clips missing ids', submission.clips);","typeGuard":"function isClipWithId(c) { return !!c && typeof c === 'object' && typeof c.id === 'string' && c.id.length > 0; }","tryCatchPattern":"try {\n  const ids = submission.clips.map(c => { if (!isClipWithId(c)) throw new Error('clip without id'); return c.id; });\n} catch (e) {\n  if (/without id/.test(e.message)) { dumpPayloadForDebugging(submission); }\n  throw e;\n}","preventionTips":["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."],"tags":["api-contract","schema-validation","data-integrity"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}