jackwener/OpenCLI · error · ArgumentError
wikidata ${label} must be a positive integer
Error message
wikidata ${label} must be a positive integer What it means
requireBoundedInt validates numeric limit-style options for the wikidata adapter. It coerces the raw value to a number and throws an ArgumentError if the result is not a strictly positive integer. This keeps invalid limits (0, negative, fractional, non-numeric) from reaching the Wikidata API.
Source
Thrown at clis/wikidata/utils.js:27
export const WIKIDATA_BASE = 'https://www.wikidata.org';
const UA = 'opencli-wikidata-adapter/1.0 (+https://github.com/jackwener/opencli; mailto:opencli@example.com)';
// Q-ID = an item; P-ID = a property; L-ID = a lexeme. We accept all three so the
// adapter can be reused for properties / lexemes without a separate command, but
// search only returns Q-IDs by default.
const ENTITY_ID_PATTERN = /^[QPL]\d+$/;
export function requireString(value, label) {
const s = String(value ?? '').trim();
if (!s) throw new ArgumentError(`wikidata ${label} cannot be empty`);
return s;
}
export function requireBoundedInt(value, defaultValue, maxValue, label = 'limit') {
const raw = value ?? defaultValue;
const n = typeof raw === 'number' ? raw : Number(raw);
if (!Number.isInteger(n) || n <= 0) {
throw new ArgumentError(`wikidata ${label} must be a positive integer`);
}
if (n > maxValue) {
throw new ArgumentError(`wikidata ${label} must be <= ${maxValue}`);
}
return n;
}
export function requireEntityId(value) {
const raw = String(value ?? '').trim().toUpperCase();
if (!raw) throw new ArgumentError('wikidata entity id is required (e.g. "Q937")');
// Tolerate URL-paste like `https://www.wikidata.org/wiki/Q937`.
const stripped = raw.replace(/^HTTPS?:\/\/[^/]+\/WIKI\//i, '');
if (!ENTITY_ID_PATTERN.test(stripped)) {
throw new ArgumentError(
`wikidata entity id "${value}" is not a valid Q/P/L identifier`,
'Expected format: "Q<digits>" (item), "P<digits>" (property), or "L<digits>" (lexeme).',
);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a positive integer, e.g. --limit 10
- Check the value's source (env var, config) for stray characters or units
- If you want 'no cap', omit the limit option rather than passing 0
- Validate with Number.isInteger in your script before invoking
Example fix
// before await runCli(['wikidata', 'search', 'cat', '--limit', '0']); // after await runCli(['wikidata', 'search', 'cat', '--limit', '10']);
Defensive patterns
Strategy: validation
Validate before calling
const n = Number(limit);
if (!Number.isInteger(n) || n <= 0) throw new Error(`limit must be a positive integer, got ${limit}`);
await runCli(['wikidata', 'search', query, '--limit', String(n)]); Type guard
function isPositiveInt(v) { return typeof v === 'number' && Number.isInteger(v) && v > 0; } Try / catch
try {
await runCli(['wikidata', 'search', query, '--limit', limit]);
} catch (e) {
if (/must be a positive integer/.test(e.message)) {
console.error(`Invalid --limit ${limit}; using default`);
} else throw e;
} Prevention
- Parse CLI numbers with Number() and validate with Number.isInteger
- Never use 0 to mean 'unlimited' — omit the flag instead
- Coerce config values to integers at load time
- Reject strings with units or stray characters early
When it happens
Trigger: Calling requireBoundedInt (via the `limit` option) with 0, a negative number, a float like 2.5, or a non-numeric string such as 'abc' or '10x'.
Common situations: Passing --limit 0 intending 'unlimited'; a CLI flag parsed from a string with stray characters; a config value of '20 items' instead of a bare number; off-by-one defaults of 0.
Related errors
- nuget ${label} must be a positive integer
- --adults must be an integer between 1 and 9, got ${JSON.stri
- tvmaze ${label} must be a positive integer
- wikidata ${label} cannot be empty
- wikidata ${label} must be <= ${maxValue}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2a3d0357534f3954.
Report an issue: GitHub.