{"record":{"id":"2a3d0357534f3954","repo":"jackwener/OpenCLI","slug":"wikidata-label-must-be-a-positive-integer","errorCode":null,"errorMessage":"wikidata ${label} must be a positive integer","messagePattern":"wikidata (.+?) must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/wikidata/utils.js","lineNumber":27,"sourceCode":"export const WIKIDATA_BASE = 'https://www.wikidata.org';\nconst UA = 'opencli-wikidata-adapter/1.0 (+https://github.com/jackwener/opencli; mailto:opencli@example.com)';\n\n// Q-ID = an item; P-ID = a property; L-ID = a lexeme. We accept all three so the\n// adapter can be reused for properties / lexemes without a separate command, but\n// search only returns Q-IDs by default.\nconst ENTITY_ID_PATTERN = /^[QPL]\\d+$/;\n\nexport function requireString(value, label) {\n    const s = String(value ?? '').trim();\n    if (!s) throw new ArgumentError(`wikidata ${label} cannot be empty`);\n    return s;\n}\n\nexport function requireBoundedInt(value, defaultValue, maxValue, label = 'limit') {\n    const raw = value ?? defaultValue;\n    const n = typeof raw === 'number' ? raw : Number(raw);\n    if (!Number.isInteger(n) || n <= 0) {\n        throw new ArgumentError(`wikidata ${label} must be a positive integer`);\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`wikidata ${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\nexport function requireEntityId(value) {\n    const raw = String(value ?? '').trim().toUpperCase();\n    if (!raw) throw new ArgumentError('wikidata entity id is required (e.g. \"Q937\")');\n    // Tolerate URL-paste like `https://www.wikidata.org/wiki/Q937`.\n    const stripped = raw.replace(/^HTTPS?:\\/\\/[^/]+\\/WIKI\\//i, '');\n    if (!ENTITY_ID_PATTERN.test(stripped)) {\n        throw new ArgumentError(\n            `wikidata entity id \"${value}\" is not a valid Q/P/L identifier`,\n            'Expected format: \"Q<digits>\" (item), \"P<digits>\" (property), or \"L<digits>\" (lexeme).',\n        );\n    }","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/wikidata/utils.js#L9-L45","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","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"],"exampleFix":"// before\nawait runCli(['wikidata', 'search', 'cat', '--limit', '0']);\n// after\nawait runCli(['wikidata', 'search', 'cat', '--limit', '10']);","handlingStrategy":"validation","validationCode":"const n = Number(limit);\nif (!Number.isInteger(n) || n <= 0) throw new Error(`limit must be a positive integer, got ${limit}`);\nawait runCli(['wikidata', 'search', query, '--limit', String(n)]);","typeGuard":"function isPositiveInt(v) { return typeof v === 'number' && Number.isInteger(v) && v > 0; }","tryCatchPattern":"try {\n    await runCli(['wikidata', 'search', query, '--limit', limit]);\n} catch (e) {\n    if (/must be a positive integer/.test(e.message)) {\n        console.error(`Invalid --limit ${limit}; using default`);\n    } else throw e;\n}","preventionTips":["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"],"tags":["validation","arguments","input-validation"],"backgroundTag":"invalid-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}