jackwener/OpenCLI · error · ArgumentError

manifestPath must point to a JSON array exported by grok/exp

Error message

manifestPath must point to a JSON array exported by grok/export

What it means

normalizeManifestRows reads rows loaded from a --manifestPath JSON file. It first checks that the parsed file is an array; this ArgumentError is thrown when it is not (object, null, string, number, etc.). The library only accepts the exact format `grok/export` produces: a top-level JSON array of conversation rows.

Source

Thrown at clis/grok/export-utils.js:77

        if (!row || typeof row !== 'object' || Array.isArray(row)) {
            throw new CommandExecutionError(`${label} returned a malformed row`, `Row ${index + 1} is not an object.`);
        }
        const id = String(row.id || '').trim().toLowerCase();
        if (!GROK_CONVERSATION_ID_RE.test(id)) {
            throw new CommandExecutionError(`${label} returned a malformed row`, `Row ${index + 1} is missing a valid Grok conversation id.`);
        }
        return {
            id,
            title: row.title == null || row.title === '' ? '' : String(row.title),
            date: row.date == null || row.date === '' ? '' : String(row.date),
            url: normalizeGrokUrl(row.url, id, (reason) => new CommandExecutionError(`${label} returned a malformed row`, reason)),
        };
    });
}

export function normalizeManifestRows(rows) {
    if (!Array.isArray(rows)) {
        throw new ArgumentError('manifestPath', 'must point to a JSON array exported by grok/export');
    }
    return rows.map((row, index) => {
        if (!row || typeof row !== 'object' || Array.isArray(row)) {
            throw new ArgumentError('manifestPath', `row ${index + 1} must be an object`);
        }
        const id = String(row.id || '').trim().toLowerCase();
        if (!GROK_CONVERSATION_ID_RE.test(id)) {
            throw new ArgumentError('manifestPath', `row ${index + 1} is missing a valid Grok conversation id`);
        }
        return {
            id,
            title: row.title == null || row.title === '' ? '' : String(row.title),
            date: row.date == null || row.date === '' ? '' : String(row.date),
            url: normalizeGrokUrl(row.url, id, (reason) => new ArgumentError('manifestPath', `row ${index + 1}: ${reason}`)),
        };
    });
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Regenerate the manifest with `grok/export` so the file is a top-level JSON array.
  2. Check the first non-whitespace character of the file: `[` means array; `{` means you have an envelope object — unwrap the rows field and pass the array instead.
  3. If you must consume an enveloped export, extract rows = parsed.conversations (or the actual array property) and normalize that.
  4. Verify the correct file is being passed to --manifestPath (easy to point at a different JSON artifact).

Example fix

// before
const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
normalizeManifestRows(parsed); // parsed = { conversations: [...] } → throws

// after
const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
const rows = Array.isArray(parsed) ? parsed : parsed.conversations;
normalizeManifestRows(rows);
Defensive patterns

Strategy: validation

Validate before calling

const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
if (!Array.isArray(parsed)) {
  throw new Error(`--manifestPath must be a JSON array; got ${parsed === null ? 'null' : typeof parsed}`);
}

Type guard

function isManifestFile(content) {
  const parsed = JSON.parse(content);
  return Array.isArray(parsed);
}

Try / catch

import { ArgumentError } from '@jackwener/opencli/errors';
try {
  const rows = normalizeManifestRows(parsed);
} catch (err) {
  if (err instanceof ArgumentError && /JSON array/.test(err.message)) {
    console.error('manifestPath file is not a grok/export JSON array — regenerate with grok/export or unwrap the rows field.');
  } else throw err;
}

Prevention

When it happens

Trigger: Passing a manifestPath whose file parses (JSON.parse succeeded) to something other than an array: e.g. an object {conversations: [...]}, a JSONL file (invalid or single-object), an empty/garbage file, or a variable holding undefined/null passed directly; detail: 'must point to a JSON array exported by grok/export'.

Common situations: Pointing --manifestPath at the wrong file (a config JSON or package.json); the export script was updated to wrap rows in an envelope object; the file was written by JSON.stringify of a single object; a newer/older CLI version changed the manifest schema.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


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