jackwener/OpenCLI · error · ArgumentError
${label} must be a path/URL or a JSON array: ${errorMessage(
Error message
${label} must be a path/URL or a JSON array: ${errorMessage(error)} What it means
An ArgumentError raised when a value that starts with '[' is treated as a JSON array but JSON.parse fails. The parsePoints-style helper accepts either a path/URL string or a literal JSON array; malformed JSON in the array form is wrapped with the underlying parse error message to help the caller fix their input.
Source
Thrown at clis/midjourney/utils.js:870
const usedMinutes = creditsToFastMinutes(Number(last.periodCreditsUsed) - Number(first.periodCreditsUsed));
if (!(elapsedDays >= 1) || !(usedMinutes > 0)) return { avgDailyMinutes: null, projectedExhaustionDate: null };
const avgDailyMinutes = Number((usedMinutes / elapsedDays).toFixed(2));
const remainingMinutes = creditsToFastMinutes(account?.total_credits ?? account?.credits_total);
const projected = remainingMinutes > 0
? new Date(Date.now() + (remainingMinutes / avgDailyMinutes) * 86_400_000).toISOString()
: null;
return { avgDailyMinutes, projectedExhaustionDate: projected };
}
export function parseReferenceArgument(value, label, { multiple = true, allowStyleCode = false } = {}) {
if (value == null || value === '') return [];
let items;
const raw = String(value).trim();
if (raw.startsWith('[')) {
try {
items = JSON.parse(raw);
} catch (error) {
throw new ArgumentError(`${label} must be a path/URL or a JSON array: ${errorMessage(error)}`);
}
} else {
items = [raw];
}
if (!Array.isArray(items) || items.length === 0 || items.some((item) => typeof item !== 'string' || !item.trim())) {
throw new ArgumentError(`${label} must contain one or more non-empty strings`);
}
if (!multiple && items.length !== 1) throw new ArgumentError(`${label} accepts exactly one reference`);
return items.map((item) => item.trim()).map((item) => {
if (allowStyleCode && /^\d+$/.test(item)) return { kind: 'styleCode', value: item };
if (/^https:\/\//i.test(item)) {
try {
const parsed = new URL(item);
const match = parsed.hostname === MIDJOURNEY_DOMAIN
? parsed.pathname.match(/^\/jobs\/([0-9a-f-]{36})\/?$/i)
: null;
if (match && UUID_RE.test(match[1])) {
const index = Number(parsed.searchParams.get('index') || 0);View on GitHub (pinned to 49907e53dc)
Solutions
- Fix the JSON so it parses: quote all strings with double quotes and remove trailing commas (e.g. ["img1.png","img2.png"])
- Validate the JSON first (JSON.parse in a REPL or a JSON linter) before passing it
- If you meant a file/URL, ensure the value does not start with '[' — otherwise it is parsed as JSON
- In shells, single-quote the argument: --points '["a.png","b.png"]' to prevent quote stripping
- If items come from another tool, serialize with JSON.stringify rather than string interpolation
Example fix
// before --prompts "['cat', 'dog']" // single quotes -> JSON.parse fails // after --prompts '["cat", "dog"]' // valid JSON array
Defensive patterns
Strategy: validation
Validate before calling
function parseItemList(value, label) {
const raw = String(value).trim();
if (raw.startsWith('[')) {
const items = JSON.parse(raw); // throws SyntaxError early with position info
if (!Array.isArray(items) || items.length === 0 || items.some((i) => typeof i !== 'string' || !i.trim())) {
throw new TypeError(`${label} must contain one or more non-empty strings`);
}
return items;
}
return [raw];
}
const items = parseItemList(cliArg, 'Images'); Try / catch
try {
await midjourney.run({ prompts: rawArg });
} catch (err) {
if (err.name === 'ArgumentError' && err.message.includes('JSON array')) {
console.error(`Invalid JSON: ${err.message}. Double-quote strings and single-quote the whole arg in shells.`);
} else throw err;
} Prevention
- Always serialize lists with JSON.stringify, never hand-write or interpolate them
- In shells, wrap JSON args in single quotes to prevent double-quote stripping
- Validate JSON input with a linter or JSON.parse dry-run before invoking the CLI
- Remember: values not starting with '[' are treated as a single path/URL, not an array
When it happens
Trigger: Passing a string beginning with '[' that is not valid JSON — e.g. "[a, b]" (unquoted items), a truncated array, or single-quoted JSON "['x','y']". Note a value merely containing brackets but not starting with '[' is treated as a path/URL instead.
Common situations: Hand-writing JSON arrays with unquoted strings or trailing commas; shell quoting stripping double quotes so '["a"]' becomes [a]; copying a JS array literal into config; empty arrays passed where at least one item is required (that case hits the sibling 'must contain one or more non-empty strings' error).
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- --limit must be a positive integer, got ${JSON.stringify(kwa
- `endoflife ${label} must be <= ${maxValue}`
- facebook search --limit must be an integer between 1 and ${M
- facebook search requires a non-empty query
- ${name} must be a positive integer
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/47522bd55af7ca34.
Report an issue: GitHub.