jackwener/OpenCLI · error · ArgumentError

--tags and --negative-tags only apply in Custom mode (alongs

Error message

--tags and --negative-tags only apply in Custom mode (alongside --lyrics).

What it means

An ArgumentError rejecting `--tags` / `--negative-tags` when `--lyrics` is absent. These flags map to the Custom-mode API fields (`tags`, `negative_tags`) which only make sense alongside lyrics; in Simple mode Suno derives style itself, so passing them indicates a mode mix-up.

Source

Thrown at clis/suno/generate.js:94

        const lyrics = kwargs.lyrics ? String(kwargs.lyrics) : '';
        const tags = kwargs.tags ? String(kwargs.tags) : '';
        const negativeTags = kwargs['negative-tags'] ? String(kwargs['negative-tags']) : '';
        const description = kwargs.prompt ? String(kwargs.prompt) : '';
        const titleArg = kwargs.title ? String(kwargs.title) : '';
        const model = kwargs.model ? String(kwargs.model).trim() : DEFAULT_SUNO_MODEL;
        if (!SUNO_MODELS.includes(model)) {
            throw new ArgumentError(`Unsupported --model "${model}"`, `Choices: ${SUNO_MODELS.join(', ')}`);
        }

        const isCustom = lyrics.trim() !== '';
        if (!isCustom && !description.trim()) {
            throw new ArgumentError(
                'Either provide a Simple-mode prompt as the positional argument, or pass --lyrics for Custom mode.',
                'Examples:\n  opencli suno generate "lo-fi study beat, 80 bpm"\n  opencli suno generate --lyrics "[Verse]\\n..." --tags "synthwave, 120 bpm"',
            );
        }
        if (!isCustom && (tags || negativeTags)) {
            throw new ArgumentError('--tags and --negative-tags only apply in Custom mode (alongside --lyrics).');
        }

        const requestedFormats = parseFormats(kwargs.formats);
        const confirmPaid = normalizeBooleanFlag(kwargs['confirm-paid']);
        const skipDownload = normalizeBooleanFlag(kwargs.sd);
        const PAID_FORMATS = new Set(['wav']);
        const skippedPaid = [];
        const formats = requestedFormats.filter(f => {
            if (PAID_FORMATS.has(f) && !confirmPaid) {
                skippedPaid.push(f);
                return false;
            }
            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);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Add --lyrics to switch to Custom mode: style tags then apply (e.g. `--lyrics "[Verse]..." --tags "synthwave"`).
  2. Or remove --tags/--negative-tags and put style hints directly in the Simple-mode prompt text.
  3. If you only want to exclude elements in Simple mode, phrase it in the description (e.g. "no vocals").
  4. Clean up script argument lists so style flags only accompany --lyrics.

Example fix

// before
opencli suno generate "synthwave song" --tags "synthwave, 120 bpm"
// after
opencli suno generate --lyrics "[Verse]\n..." --tags "synthwave, 120 bpm"
Defensive patterns

Strategy: validation

Validate before calling

// style flags only make sense in Custom mode
const useCustom = Boolean(lyrics?.trim());
if (!useCustom && (tags || negativeTags)) {
  throw new Error('--tags/--negative-tags require --lyrics (Custom mode)');
}

Try / catch

try {
  await run('opencli suno generate ...');
} catch (err) {
  if (String(err.message).includes('only apply in Custom mode')) {
    // either add --lyrics or move style hints into the prompt text and retry
  } else throw err;
}

Prevention

When it happens

Trigger: Running `opencli suno generate "<prompt>" --tags "..."` (or --negative-tags) without --lyrics. The CLI computes isCustom = lyrics.trim() !== '' and throws when style flags appear in Simple mode.

Common situations: Users who want to steer style in Simple mode (unsupported — use Custom mode instead), leftover flags in scripts from a previous Custom-mode invocation, or misunderstanding that --tags requires --lyrics.

Related errors


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