{"record":{"id":"58af57fb98be8998","repo":"jackwener/OpenCLI","slug":"all-requested-formats-require-confirm-paid-true","errorCode":null,"errorMessage":"All requested formats require --confirm-paid true","messagePattern":"All requested formats require --confirm-paid true","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/suno/download.js","lineNumber":78,"sourceCode":"        { name: 'op', help: 'Output directory (default: ~/Music/suno)' },\n        { name: 'confirm-paid', type: 'boolean', default: false, help: 'Required to allow paid downloads (wav). Without it, paid formats are skipped with a warning.' },\n    ],\n    columns: ['status', 'clip', 'title', 'files', 'link'],\n    func: async (page, kwargs) => {\n        const clipId = parseClipId(kwargs.clip);\n        const requestedFormats = parseFormats(kwargs.formats);\n        const confirmPaid = normalizeBooleanFlag(kwargs['confirm-paid']);\n        const PAID_FORMATS = new Set(['wav']);\n        const skippedPaid = [];\n        const formats = requestedFormats.filter(f => {\n            if (PAID_FORMATS.has(f) && !confirmPaid) {\n                skippedPaid.push(f);\n                return false;\n            }\n            return true;\n        });\n        if (!formats.length) {\n            throw new ArgumentError('All requested formats require --confirm-paid true', 'Add --confirm-paid true or include a free format such as mp3 or metadata.');\n        }\n        const outputDir = resolveSunoOutputDir(kwargs.op);\n\n        const session = await ensureSunoSession(page);\n        const deviceId = session.deviceId;\n\n        // Pull the clip object from feed/v3 so audio_url/media_urls/has_stem are current.\n        const feedRes = unwrapEvaluateResult(await page.evaluate(`(async () => {\n            const browserToken = JSON.stringify({ token: btoa(JSON.stringify({ timestamp: Date.now() })) });\n            const res = await fetch('${STUDIO_API}/api/feed/v3', {\n                method: 'POST',\n                headers: {\n                    'Authorization': 'Bearer ' + (await window.Clerk.session.getToken()),\n                    'browser-token': browserToken,\n                    'device-id': ${JSON.stringify(deviceId)},\n                    'Content-Type': 'application/json',\n                },\n                body: JSON.stringify({ clip_ids: ['${clipId}'] }),","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/suno/download.js#L60-L96","documentation":"The download command filters requested formats against a paid set (wav). If every requested format is paid and --confirm-paid is not true, no work would be done silently, so the command throws ArgumentError telling you to add --confirm-paid true or include a free format. This guards against Suno's per-download billing for WAV.","triggerScenarios":"Running `opencli suno download <id> --formats wav` (only a paid format) without `--confirm-paid true`, so the format filter empties the list.","commonSituations":"Defaulting --formats to wav in a script; forgetting that wav triggers billing; combining a paid-only format list with the flag misspelled (e.g. confirm_paid) so it stays false.","solutions":["Add `--confirm-paid true` to accept the WAV per-download charge","Or include a free format: `--formats mp3` or `--formats metadata` (or default mp3,metadata)","Check flag spelling — it is `--confirm-paid` (boolean, default false)"],"exampleFix":"// before\nawait cli('suno', 'download', id, '--formats', 'wav'); // ArgumentError\n// after\nawait cli('suno', 'download', id, '--formats', 'wav', '--confirm-paid', 'true');\n// or free alternative:\nawait cli('suno', 'download', id, '--formats', 'mp3');","handlingStrategy":"validation","validationCode":"const requested = (formats || 'mp3,metadata').split(',');\nconst paid = requested.filter(f => f === 'wav');\nif (paid.length && confirmPaid !== true) {\n  console.warn('wav requires --confirm-paid true (per-download billing); adding free formats or the flag');\n}","typeGuard":"function isPaidFormatSafe(formats, confirmPaid) {\n  const paid = ['wav'];\n  return !formats.some(f => paid.includes(f)) || confirmPaid === true;\n}","tryCatchPattern":"try {\n  await cli('suno', 'download', id, '--formats', formats);\n} catch (e) {\n  if (/--confirm-paid/.test(e.message)) {\n    return cli('suno', 'download', id, '--formats', formats, '--confirm-paid', 'true');\n  }\n  throw e;\n}","preventionTips":["Always pass --confirm-paid true explicitly when WAV downloads (billing) are intended","Include a free format (mp3/metadata) alongside wav so the command partially succeeds without the flag","Spell the flag exactly as --confirm-paid (boolean, default false)","Audit automated scripts for paid formats to avoid unexpected Suno charges"],"tags":["validation","billing","paid-content","cli"],"backgroundTag":"confirmation-flag-required","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}