jackwener/OpenCLI · error · CommandExecutionError

archive search returned malformed payload for "${id}": downl

Error message

archive search returned malformed payload for "${id}": downloads must be numeric

What it means

CommandExecutionError thrown in `opencli archive search` when a result row's `downloads` field, after `Number(d.downloads ?? 0)`, is not finite (e.g. a non-numeric string). The library coerces missing downloads to 0 but refuses rows where the value exists yet is not numeric, since ranking output would be corrupted.

Source

Thrown at clis/archive/search.js:100

            throw new CommandExecutionError(`archive search returned malformed JSON: ${error?.message || error}`);
        }

        const docs = data?.response?.docs;
        if (!Array.isArray(docs)) {
            throw new CommandExecutionError('archive search returned malformed payload: response.docs must be an array');
        }
        if (docs.length === 0) {
            throw new EmptyResultError('archive search', `No items match "${query}" on archive.org.`);
        }

        return docs.slice(0, limit).map((d, i) => {
            const id = String(d.identifier ?? '');
            if (!IDENTIFIER_RE.test(id)) {
                throw new CommandExecutionError('archive search returned malformed payload: result row is missing a stable identifier');
            }
            const downloads = Number(d.downloads ?? 0);
            if (!Number.isFinite(downloads)) {
                throw new CommandExecutionError(`archive search returned malformed payload for "${id}": downloads must be numeric`);
            }
            const creator = Array.isArray(d.creator) ? d.creator.join(', ') : String(d.creator ?? '');
            return {
                rank: i + 1,
                identifier: id,
                title: String(d.title ?? ''),
                creator,
                date: d.date ? String(d.date).slice(0, 10) : '',
                mediatype: String(d.mediatype ?? ''),
                downloads,
                url: id ? `https://archive.org/details/${id}` : '',
            };
        });
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the query — this is often transient bad data from archive.org.
  2. Inspect the offending row via https://archive.org/advancedsearch.php with the same query to confirm the downloads value's type.
  3. Narrow the query to avoid the problematic item if one specific row is corrupt.
  4. Report the malformed row upstream if it persists.
Defensive patterns

Strategy: validation

Validate before calling

// Check downloads field type on the raw payload before invoking the CLI mapping
const bad = docs.filter(d => {
  const n = Number(d.downloads ?? 0);
  return !Number.isFinite(n);
});
if (bad.length) console.warn(`rows with non-numeric downloads: ${bad.map(b => b.identifier)}`);

Type guard

function hasNumericDownloads(row) {
  return Number.isFinite(Number(row?.downloads ?? 0));
}

Try / catch

try {
  const rows = await run(['archive', 'search', query]);
} catch (e) {
  if (/downloads must be numeric/.test(e.message)) {
    const id = e.message.match(/for "([^"]+)"/)?.[1];
    console.warn(`bad downloads value for item ${id}; refetching or skipping`);
  } else throw e;
}

Prevention

When it happens

Trigger: A docs row contains downloads as a non-numeric value (object, weird string) so Number.isFinite(Number(...)) is false; the row already passed the identifier check, so the error message carries that identifier.

Common situations: archive.org returning inconsistent field types across rows; schema drift in the search API; cached/proxied responses with altered field values.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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