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
- Pass a real boolean: fetchHistory({ all: true }).
- Coerce string options with a strict parser (only 'true'/'false' accepted) before calling fetchHistory.
- If using a CLI parser, enable automatic boolean typing (e.g. commander's .option('--all') or yargs' boolean: ['all']).
- 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
- Use a CLI parser with boolean option typing.
- Strictly coerce string flags ('true'/'false') before calling.
- Document expected argument types for fetchHistory.
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
- <train-no> "${trainNo}" does not look like a 12306 internal
- --from station must not be empty
- --to station must not be empty
- --seat-types must contain only 12306 seat letters/digits (A-
- --from and --to must differ; both resolved to ${fromStation.
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/46afe484f55b8746.
Report an issue: GitHub.