jackwener/OpenCLI · error · AuthRequiredError

${probe.detail}

Error message

${probe.detail}

What it means

When the in-page Clerk /v1/client probe returns kind 'auth' (HTTP 401/403, sessions=[] anonymous, or a session with no user.id), verifySunoIdentity re-throws that detail as an AuthRequiredError for suno.com. It means the browser reached Clerk but Clerk says there is no usable authenticated session.

Source

Thrown at clis/suno/auth.js:43

        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' };
      }
      const active = sessions.find(s => s.status === 'active') || sessions[0];
      const user = active?.user;
      if (!user?.id) {
        return { kind: 'auth', detail: 'clerk.suno.com session present but no user.id — stale session' };
      }
      return { ok: true, user_id: String(user.id), name: String(user.username || '') };
    } catch (e) {
      return { kind: 'exception', detail: String(e && e.message || e) };
    }
  })()`);
  if (probe?.kind === 'auth') throw new AuthRequiredError('suno.com', probe.detail);
  if (probe?.kind === 'http') throw new CommandExecutionError(`HTTP ${probe.httpStatus} from clerk.suno.com`);
  if (probe?.kind === 'exception') throw new CommandExecutionError(`Suno whoami failed: ${probe.detail}`);
  if (!probe?.ok) throw new CommandExecutionError(`Unexpected Suno probe: ${JSON.stringify(probe)}`);
  return { user_id: probe.user_id, name: probe.name };
}

registerSiteAuthCommands({
  site: 'suno',
  domain: 'suno.com',
  loginUrl: 'https://suno.com/?sign-in=true',
  columns: ['user_id', 'name'],
  quickCheck: hasSunoClerkCookie,
  verify: verifySunoIdentity,
  poll: async (page) => {
    if (!await hasSunoClerkCookie(page)) {
      throw new AuthRequiredError('suno.com', 'Waiting for Suno Clerk __session/__client cookie');
    }
    return verifySunoIdentity(page);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the suno login flow to mint a fresh __session token
  2. Clear cookies for suno.com and clerk.suno.com, then log in again
  3. If 'stale session' repeats, sign out everywhere on Suno's web UI and log back in
  4. Retry after confirming https://suno.com loads and shows you logged in in the same browser profile

Example fix

// before
if (probe?.kind === 'auth') throw new AuthRequiredError('suno.com', probe.detail);
// after (caller side recovery)
try { await cli('suno', 'whoami'); }
catch (e) { if (e instanceof AuthRequiredError) await cli('suno', 'login'); }
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify auth with a cheap call first
try { await cli('suno', 'whoami'); } catch { await cli('suno', 'login'); }

Type guard

function isAuthRequiredError(e) {
  return e instanceof Error && (e.name === 'AuthRequiredError' || /clerk\.suno\.com/.test(e.message));
}

Try / catch

try {
  const me = await cli('suno', 'whoami');
} catch (e) {
  if (isAuthRequiredError(e)) { await cli('suno', 'login'); return cli('suno', 'whoami'); }
  throw e;
}

Prevention

When it happens

Trigger: The `__session` cookie existed but Clerk rejected it (401/403), returned zero sessions, or returned a session object with no user.id (stale session) during verifySunoIdentity.

Common situations: Expired or revoked Clerk JWT that still sits in the cookie jar; Suno rotated Clerk instance keys; account signed out server-side (another device or password change); stale session record left after an incomplete login.

Related errors


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