jackwener/OpenCLI · error · ArgumentError

--all must be a boolean

Error message

--all must be a boolean

What it means

fetchHistory expects args.all to be a strict boolean (defaulting to false). Passing any other type makes the --all flag's intent ambiguous, so an ArgumentError is thrown before any network call.

Source

Thrown at clis/xiaoyuzhou/history.js:150

        progressById.set(eid, {
            progressSec,
            playedAt: optionalIsoTime(row.playedAt, `playedAt in row ${index + 1}`),
        });
    }
    for (const episode of episodes) {
        if (!progressById.has(episode.eid)) {
            throw new CommandExecutionError(
                `Xiaoyuzhou playback progress omitted requested eid ${episode.eid}; the history join is incomplete`,
            );
        }
    }
    return progressById;
}

async function fetchHistory(args = {}) {
    const fetchAll = args.all ?? false;
    if (typeof fetchAll !== 'boolean') {
        throw new ArgumentError('--all must be a boolean');
    }
    const limit = fetchAll ? null : positiveInteger(args.limit ?? DEFAULT_LIMIT, 'limit', MAX_LIMIT);
    const maxPages = positiveInteger(args['max-pages'] ?? DEFAULT_MAX_PAGES, 'max-pages', HARD_MAX_PAGES);
    let credentials = loadXiaoyuzhouCredentials();
    const seenEpisodeIds = new Set();
    const seenCursors = new Set();
    const rows = [];
    let loadMoreKey = null;
    let exhausted = false;

    for (let pageNumber = 1; pageNumber <= maxPages; pageNumber += 1) {
        const historyResponse = await requestXiaoyuzhouJson(HISTORY_ENDPOINT, {
            method: 'POST',
            body: loadMoreKey === null ? {} : { loadMoreKey },
            credentials,
        });
        credentials = historyResponse.credentials;
        const page = parseHistoryPage(historyResponse);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a real boolean: fetchHistory({ all: true }).
  2. Coerce string options with a strict parser (only 'true'/'false' accepted) before calling fetchHistory.
  3. If using a CLI parser, enable automatic boolean typing (e.g. commander's .option('--all') or yargs' boolean: ['all']).
  4. Audit config-loading code so all/limit/max-pages arrive with documented types.

Example fix

// before
await fetchHistory({ all: process.env.HISTORY_ALL });
// after
const all = process.env.HISTORY_ALL === 'true' ? true
  : process.env.HISTORY_ALL === 'false' ? false
  : undefined;
await fetchHistory({ all });
Defensive patterns

Strategy: type-guard

Validate before calling

if (args.all !== undefined && typeof args.all !== 'boolean') {
  throw new TypeError('all must be a boolean');
}

Type guard

const isBoolean = (v) => typeof v === 'boolean';
const parseBoolFlag = (v) => v === undefined ? undefined
  : v === 'true' ? true : v === 'false' ? false : null;

Try / catch

try {
  await fetchHistory(args);
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('--all')) {
    console.error('Pass --all as a true/false boolean');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling fetchHistory({ all: 'true' }), fetchHistory({ all: 1 }), or similar truthy non-boolean values from CLI-parsed options or hand-assembled argument objects.

Common situations: CLI frameworks delivering options as strings ('true'/'false'); env-var-driven config where everything is a string; migrating code that previously relied on truthiness; YAML/JSON config with quoted versus unquoted booleans.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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