jackwener/OpenCLI · error · CommandExecutionError

Suno generation needs a resolved plan id for the user_tier f

Error message

Suno generation needs a resolved plan id for the user_tier field, but billing/info did not surface one for this account (subscription_type=${session.planKey}). Verify the account is active at ${SUNO_URL}/account, then retry.

What it means

A CommandExecutionError thrown after `ensureSunoSession(page)` when the session's billing/info response did not yield a `planId`. The generation API requires a `user_tier` field derived from the resolved plan id, so the CLI aborts instead of submitting a request with an undefined tier. `subscription_type=<planKey>` in the message shows the raw key Suno returned (which failed to map to a plan id).

Source

Thrown at clis/suno/generate.js:124

            }
            return true;
        });
        if (!skipDownload && !formats.length) {
            throw new ArgumentError('All requested formats require --confirm-paid true', 'Add --confirm-paid true or include a free format such as mp3 or metadata.');
        }
        const outputDir = resolveSunoOutputDir(kwargs.op);
        const timeout = requirePositiveInt(kwargs.timeout, '--timeout');
        const makeInstrumental = normalizeBooleanFlag(kwargs.instrumental);
        const weirdness = clampSlider(kwargs.weirdness, '--weirdness', 0.5);
        const styleWeight = clampSlider(kwargs['style-weight'], '--style-weight', 0.5);

        // Title: required by API. Auto-derive from first 60 chars of source prompt if not provided.
        const titleSource = titleArg || (isCustom ? (tags || lyrics.split('\n')[0]) : description);
        const title = titleSource.replace(/\s+/g, ' ').trim().slice(0, 60) || 'Untitled';

        const session = await ensureSunoSession(page);
        if (!session.planId) {
            throw new CommandExecutionError(
                `Suno generation needs a resolved plan id for the user_tier field, but billing/info did not surface one for this account (subscription_type=${session.planKey}). Verify the account is active at ${SUNO_URL}/account, then retry.`,
            );
        }
        const deviceId = session.deviceId;
        const captcha = await checkSunoCaptcha(page, deviceId);
        if (!captcha?.ok) {
            throw new CommandExecutionError(
                `Suno captcha pre-flight failed${captcha?.status ? ` (HTTP ${captcha.status})` : ''}.`,
                `Open ${SUNO_URL}/create in Chrome and verify the account is ready, then retry.`,
            );
        }
        if (captcha?.required) {
            throw new CommandExecutionError(
                'Suno requires a CAPTCHA challenge for this account/IP right now.',
                `Open ${SUNO_URL}/create in Chrome, solve a Create challenge once, then retry.`,
            );
        }
        if (session.totalCreditsAvailable < 10) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the account is active and has an identifiable plan at https://suno.com/account, then retry the command.
  2. Refresh the session: log out/in (or re-open suno.com in the driven Chrome profile) so billing/info returns fresh data, then retry.
  3. Check the printed subscription_type value — if it's a new/unrecognized plan key, upgrade @jackwener/opencli so its plan mapping includes it.
  4. If the account is fine and the CLI is current, file an issue with the subscription_type string from the message.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the account has an active subscription before generating
// open suno.com/account in the driven profile and confirm a plan is shown,
// then retry; scripts can pre-check via the CLI session or billing/info response

Type guard

const sessionHasPlan = (session) =>
  session != null && typeof session === 'object' &&
  typeof session.planId === 'string' && session.planId.length > 0;

Try / catch

try {
  await run('opencli suno generate "..."');
} catch (err) {
  if (String(err.message).includes('resolved plan id')) {
    // re-login to suno.com, verify the account/plan, upgrade the CLI if
    // subscription_type is a new key, then retry
  } else throw err;
}

Prevention

When it happens

Trigger: Running `opencli suno generate` with a logged-in Suno account whose billing/info response lacks a mappable plan — e.g. brand-new/free accounts with an unrecognized subscription_type string, Suno renaming plan keys, or a stale/soft-failing session where billing/info returns an unexpected body.

Common situations: Newly created Suno accounts, accounts mid-downgrade/expired subscription, Suno changing its subscription_type vocabulary after a product update, or an outdated CLI whose plan-key mapping predates Suno's current plan names.

Related errors


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