jackwener/OpenCLI · error · ArgumentError
Either provide a Simple-mode prompt as the positional argume
Error message
Either provide a Simple-mode prompt as the positional argument, or pass --lyrics for Custom mode.
What it means
An ArgumentError enforcing that `opencli suno generate` needs at least one input: either a positional prompt (Simple mode, where Suno writes lyrics/tags itself) or `--lyrics` (Custom mode). Without either there is nothing to send as the generation `prompt`, which the API requires.
Source
Thrown at clis/suno/generate.js:88
{ name: 'timeout', type: 'int', default: 300, help: 'Max seconds to wait for clips to finish (default: 300)' },
{ name: 'sd', type: 'boolean', default: false, help: 'Skip download; only print clip ids and Suno URLs' },
{ name: 'confirm-paid', type: 'boolean', default: false, help: 'Required to allow paid downloads (wav). Without it, paid formats are skipped with a warning.' },
],
columns: ['status', 'clip', 'title', 'files', 'link'],
func: async (page, kwargs) => {
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;
}View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a Simple-mode description as the positional argument: `opencli suno generate "lo-fi study beat, 80 bpm"`.
- Or use Custom mode: `opencli suno generate --lyrics "[Verse]..." --tags "synthwave, 120 bpm"`.
- If scripting, check the prompt/lyrics variables are non-empty before invoking the command.
- Quote the prompt so spaces don't split it into stray positional tokens.
Example fix
// before opencli suno generate --tags "synthwave" // after opencli suno generate "retro synthwave, 110 bpm" --tags "synthwave" # or add --lyrics for custom mode
Defensive patterns
Strategy: validation
Validate before calling
import { execFileSync } from 'node:child_process';
const prompt = process.argv[2] ?? '';
const lyrics = process.env.LYRICS ?? '';
if (!prompt.trim() && !lyrics.trim()) {
throw new Error('need a positional prompt or --lyrics');
}
execFileSync('opencli', ['suno', 'generate', prompt].filter(Boolean), { stdio: 'inherit' }); Type guard
const hasInput = (prompt, lyrics) => (typeof prompt === 'string' && prompt.trim() !== '') || (typeof lyrics === 'string' && lyrics.trim() !== '');
Try / catch
try {
await run('opencli suno generate ' + args);
} catch (err) {
if (String(err.message).includes('Simple-mode prompt')) {
// re-invoke with a positional prompt or --lyrics
} else throw err;
} Prevention
- Always pass the prompt in quotes so shell word-splitting doesn't drop it.
- In scripts, assert prompt/lyrics variables are non-empty before invoking.
- Remember flags alone never constitute a generation request.
When it happens
Trigger: Running `opencli suno generate` with no positional prompt and no --lyrics — e.g. only passing flags like --tags/--instrumental/--model, quoting mistakes that drop the positional argument, or shell-embedded prompts expanding to an empty string.
Common situations: Forgetting the positional description, an empty shell variable (`$PROMPT` unset) consumed as the positional arg, or assuming flags alone constitute a request.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- keyword must not be empty
- <from> station must not be empty
- <to> station must not be empty
- who 不能为空
- key is required
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a745b3403ea88db0.
Report an issue: GitHub.