{"record":{"id":"586ee59c8697c90e","repo":"jackwener/OpenCLI","slug":"suno-session-check-failed-detail-open-https","errorCode":null,"errorMessage":"Suno session check failed (${detail}). Open https://suno.com in Chrome and sign in, then retry.","messagePattern":"Suno session check failed \\((.+?)\\)\\. Open https://suno\\.com in Chrome and sign in, then retry\\.","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/suno/utils.js","lineNumber":207,"sourceCode":"            const res = await fetch('${STUDIO_API}/api/billing/info/', { headers: ${sunoHeadersJs(deviceId)} });\n            if (!res.ok) return { ok: false, status: res.status, body: (await res.text()).slice(0, 300) };\n            let data = null;\n            try {\n                data = await res.json();\n            } catch (e) {\n                return { ok: false, error: 'Malformed billing/info JSON: ' + String(e).slice(0, 200) };\n            }\n            const parse = ${parseSunoBillingInfo.toString()};\n            return { ok: true, ...parse(data) };\n        } catch (e) {\n            return { ok: false, error: String(e).slice(0, 200) };\n        }\n    })()`));\n\n    if (!result || !result.ok) {\n        const detail = result?.status || result?.error || 'unknown';\n        if (result?.auth || result?.status === 401 || result?.status === 403) {\n            throw new AuthRequiredError(SUNO_DOMAIN, `Suno session check failed (${detail}). Open https://suno.com in Chrome and sign in, then retry.`);\n        }\n        throw new CommandExecutionError(`Suno session check failed (${detail}).`);\n    }\n    return { ...result, deviceId };\n}\n\n/**\n * Verify the captcha pre-flight. If `required:true`, the simple flow won't\n * work without solving a CAPTCHA (out of scope for the headless adapter).\n */\nexport async function checkSunoCaptcha(page, deviceId) {\n    const result = unwrapEvaluateResult(await page.evaluate(`(async () => {\n        const res = await fetch('${STUDIO_API}/api/c/check', {\n            method: 'POST',\n            headers: ${sunoHeadersJs(deviceId, { 'Content-Type': 'application/json' })},\n            body: JSON.stringify({ ctype: 'generation' }),\n        });\n        if (!res.ok) return { ok: false, status: res.status };","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/suno/utils.js#L189-L225","documentation":"ensureSunoSession runs an in-browser check of your suno.com Clerk session before API calls. When the check fails with an auth signal (result.auth true, or HTTP 401/403), it throws AuthRequiredError telling you to open suno.com in Chrome and sign in, since the CLI reuses your browser's JWT.","triggerScenarios":"Running any suno command when you are logged out of suno.com in the automated Chrome profile, your Clerk JWT expired, or the session endpoint returns 401/403 (e.g. stale cookies after a password change or Cloudflare challenge).","commonSituations":"Chrome profile signed out after cookie eviction or incognito use; expired Clerk session after long idle; logging in on a different browser than the one the CLI drives; suno.com invalidated all sessions (password change, security event).","solutions":["Open https://suno.com in the Chrome instance the CLI controls and sign in, then retry the command.","Clear suno.com cookies for that profile and log in again to remove stale/invalid session state.","Verify you are not in an incognito/isolated profile where the Clerk cookie is dropped.","If the status is 403 persistently, check for a captcha/Cloudflare challenge on suno.com and complete it in the browser first.","Update the CLI in case Suno changed its auth endpoints and a newer version handles the new flow."],"exampleFix":"// before (headless invocation with no signed-in profile)\nopencli suno list   // -> AuthRequiredError\n// after (ensure sign-in first, then run)\n// 1. open https://suno.com in Chrome and log in\nopencli suno list","handlingStrategy":"try-catch","validationCode":"// Pre-flight: verify sign-in state before running commands\nconst ok = await ensureSunoSession(page, deviceId).then(() => true).catch(() => false);\nif (!ok) console.error('Sign in at https://suno.com in the automated Chrome first.');","typeGuard":"function isAuthRequiredError(err) {\n  return err && (err.name === 'AuthRequiredError' || /session check failed.*sign in/i.test(err.message || ''));\n}","tryCatchPattern":"try {\n  await ensureSunoSession(page, deviceId);\n  await runCommand();\n} catch (err) {\n  if (isAuthRequiredError(err)) {\n    console.error('Open https://suno.com in Chrome, sign in, then retry.');\n    process.exitCode = 2; // distinct auth exit code\n  } else throw err;\n}","preventionTips":["Sign in to suno.com in the exact Chrome profile the CLI drives before long sessions.","Re-login after password changes or known session invalidations.","Run `suno status` as a cheap pre-flight before expensive operations.","Avoid incognito/isolated profiles that drop the Clerk session cookie."],"tags":["auth","suno","session-expired","browser-automation"],"backgroundTag":"auth-session-expired","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}