jackwener/OpenCLI · error · ArgumentError
Provide --card-text (text-image mode) or --images (upload mo
Error message
Provide --card-text (text-image mode) or --images (upload mode); neither was given.
What it means
ArgumentError thrown when neither publish mode was supplied: no --card-text (text-image/文字配图 mode) and no --images (upload mode). The command requires exactly one of these two content sources and refuses to continue otherwise.
Source
Thrown at clis/xiaohongshu/publish.js:1206
const topics = kwargs.topics
? String(kwargs.topics).split(',').map((s) => s.trim()).filter(Boolean)
: [];
const isDraft = Boolean(kwargs.draft);
const cardText = kwargs['card-text'] ? String(kwargs['card-text']) : '';
const cards = cardText
? cardText.split(CARD_TEXT_DELIM).map((s) => s.trim()).filter(Boolean)
: [];
const cardStyle = kwargs['card-style'] ? String(kwargs['card-style']).trim() : '';
const isTextImage = cards.length > 0;
// ── Validate inputs ────────────────────────────────────────────────────────
if (!title)
throw new ArgumentError('--title is required');
if (title.length > MAX_TITLE_LEN)
throw new ArgumentError(`Title is ${title.length} chars — must be ≤ ${MAX_TITLE_LEN}`);
if (!content)
throw new ArgumentError('Positional argument <content> is required');
if (!isTextImage && imagePaths.length === 0)
throw new ArgumentError('Provide --card-text (text-image mode) or --images (upload mode); neither was given.');
if (imagePaths.length > MAX_IMAGES)
throw new ArgumentError(`Too many images: ${imagePaths.length} (max ${MAX_IMAGES})`);
// The editor-page image input (text-image append) rejects gif.
if (isTextImage && imagePaths.some((p) => path.extname(p).toLowerCase() === '.gif'))
throw new ArgumentError('文字配图模式追加的图片不支持 .gif(编辑器图片入口只接受 jpg/jpeg/png/webp)');
// Validate image paths before navigating (fast-fail on bad paths / unsupported formats)
const absImagePaths = validateImagePaths(imagePaths);
// ── Step 1: Navigate to publish page ──────────────────────────────────────
await page.goto(PUBLISH_URL);
await page.wait({ time: 3 });
// Verify we landed on the creator site (not redirected to login)
const pageUrl = await page.evaluate('() => location.href');
if (!pageUrl.includes('creator.xiaohongshu.com')) {
throw new Error('Redirected away from creator center — session may have expired. ' +
'Re-capture browser login via: opencli xiaohongshu creator-profile');
}
// ── Step 2: Select 图文 (image+text) note type if tabs are present ─────────
const tabResult = await selectImageTextTab(page);View on GitHub (pinned to 49907e53dc)
Solutions
- Add --card-text "第一张|第二张" for text-image mode, or
- Add --images "a.jpg,b.png" for upload mode
- Check flag spelling — the flags are exactly --card-text and --images
Example fix
// before node publish.js --title "标题" "正文" // after node publish.js --title "标题" "正文" --images "./pic1.jpg,./pic2.jpg"
Defensive patterns
Strategy: validation
Validate before calling
const hasImages = imagesFlag && imagesFlag.trim().length > 0;
const hasCards = cardTextFlag && cardTextFlag.trim().length > 0;
if (!hasImages && !hasCards) throw new Error('Provide --card-text or --images'); Type guard
function hasPublishSource(kwargs) {
return Boolean(
(kwargs.images && String(kwargs.images).trim()) ||
(kwargs['card-text'] && String(kwargs['card-text']).trim())
);
} Try / catch
try {
await publish(page, kwargs);
} catch (e) {
if (String(e.message).includes('neither was given')) {
console.error('Add --card-text "a|b" (text-image) or --images "1.jpg,2.jpg" (upload)');
}
throw e;
} Prevention
- Decide the mode (text-image vs upload) before composing the command
- Check exact flag spellings: --card-text and --images
- Dry-run validation of the full argument set in CI wrappers
When it happens
Trigger: Running publish with --title and content but omitting both --card-text and --images, so isTextImage is false and imagePaths.length === 0.
Common situations: Thinking content alone is enough to publish (XHS requires at least one image or generated card images); misspelling the flags (--image, --cards); shell quoting causing the flag value to be parsed away.
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
- --title is required
- Title is ${title.length} chars — must be ≤ ${MAX_TITLE_LEN}
- Positional argument <content> is required
- Too many images: ${imagePaths.length} (max ${MAX_IMAGES})
- INVALID_ARGUMENT
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0cc317865efcff45.
Report an issue: GitHub.