jackwener/OpenCLI · error · AuthRequiredError

Suno Clerk __session/__client cookie missing

Error message

Suno Clerk __session/__client cookie missing

What it means

verifySunoIdentity() checks the browser's cookie jar for a non-empty Clerk `__session` cookie before probing Suno's identity API. Clerk only sets `__session` (the session JWT) once you are actually authenticated; `__client` alone just marks an anonymous visitor. If the cookie is missing the library throws AuthRequiredError for suno.com, telling you to log in first.

Source

Thrown at clis/suno/auth.js:14

import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors';
import { registerSiteAuthCommands } from '../_shared/site-auth.js';

async function hasSunoClerkCookie(page) {
  const cookies = await page.getCookies({ url: 'https://clerk.suno.com' });
  // Clerk sets __client for anonymous sessions too; __session (the session JWT)
  // is present only when authenticated, so gate on it to avoid navigating away
  // mid-login.
  return cookies.some(c => c.name === '__session' && c.value);
}

async function verifySunoIdentity(page) {
  if (!await hasSunoClerkCookie(page)) {
    throw new AuthRequiredError('suno.com', 'Suno Clerk __session/__client cookie missing');
  }
  await page.goto('https://suno.com/');
  await page.wait(2);
  const probe = await page.evaluate(`(async () => {
    try {
      const r = await fetch('https://clerk.suno.com/v1/client?_clerk_js_version=5', {
        credentials: 'include',
        headers: { Accept: 'application/json' },
      });
      if (r.status === 401 || r.status === 403) {
        return { kind: 'auth', detail: 'clerk.suno.com /v1/client HTTP ' + r.status };
      }
      if (!r.ok) return { kind: 'http', httpStatus: r.status };
      const d = await r.json();
      const sessions = d?.response?.sessions || [];
      if (!Array.isArray(sessions) || sessions.length === 0) {
        return { kind: 'auth', detail: 'clerk.suno.com sessions=[] — anonymous' };
      }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run the site's login flow (loginUrl https://suno.com/?sign-in=true) and complete sign-in in the persistent browser
  2. Re-run the command after login completes
  3. If it persists, clear suno.com/clerk.suno.com cookies and log in again — a stale Clerk state can block issuance of a fresh __session
  4. Check that the browser profile used is the same one opencli persists (not an incognito/isolated context)

Example fix

// before (no session)
await cli('suno', 'whoami'); // -> AuthRequiredError: Suno Clerk __session/__client cookie missing
// after
await cli('suno', 'login');   // complete interactive sign-in
await cli('suno', 'whoami');
Defensive patterns

Strategy: validation

Validate before calling

const cookies = await page.getCookies({ url: 'https://clerk.suno.com' });
if (!cookies.some(c => c.name === '__session' && c.value)) {
  await cli('suno', 'login'); // obtain a session before running commands
}

Type guard

function hasSessionCookie(cookies) {
  return Array.isArray(cookies) && cookies.some(c => c.name === '__session' && !!c.value);
}

Try / catch

try {
  await cli('suno', 'whoami');
} catch (e) {
  if (e.name === 'AuthRequiredError' || /cookie missing/.test(e.message)) {
    await cli('suno', 'login');
    return cli('suno', 'whoami');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `opencli suno whoami`/auth verify (or any suno command that calls verifySunoIdentity) while the persistent browser profile for suno.com has no non-empty `__session` cookie — i.e. never logged in, logged out, or the Clerk session expired/was revoked.

Common situations: Fresh machine or wiped browser profile; Suno/Clerk session expired (JWT TTL elapsed); using a profile that only ever reached the login page; cookie cleared by privacy settings or a concurrent process navigating away mid-login.

Related errors


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