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

  1. Fix the JSON so it parses: quote all strings with double quotes and remove trailing commas (e.g. ["img1.png","img2.png"])
  2. Validate the JSON first (JSON.parse in a REPL or a JSON linter) before passing it
  3. If you meant a file/URL, ensure the value does not start with '[' — otherwise it is parsed as JSON
  4. In shells, single-quote the argument: --points '["a.png","b.png"]' to prevent quote stripping
  5. 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

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


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