{"record":{"id":"3b68beffd87d2a69","repo":"jackwener/OpenCLI","slug":"wikidata-label-must-be-maxvalue","errorCode":null,"errorMessage":"wikidata ${label} must be <= ${maxValue}","messagePattern":"wikidata (.+?) must be <= (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/wikidata/utils.js","lineNumber":30,"sourceCode":"// 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    }\n    return stripped;\n}\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/wikidata/utils.js#L12-L48","documentation":"requireBoundedInt enforces an upper bound on numeric options like limit. Once the value is confirmed to be a positive integer, it throws an ArgumentError if it exceeds the adapter's configured maximum for that option. This protects the Wikidata API (and response size) from unbounded requests.","triggerScenarios":"Calling requireBoundedInt (via `limit`) with a value above the command's maxValue, e.g. `wikidata search cat --limit 100` when the cap is 50.","commonSituations":"Assuming the limit is unbounded or has a higher cap than it does; copying a limit from another tool with a bigger maximum; scripts computing limits from result-set sizes.","solutions":["Lower the limit to the documented maximum for the command (check --help for the cap)","Clamp the value in your script: Math.min(limit, maxValue)","If a larger cap is genuinely needed, fetch multiple pages/batches instead of raising one request's limit"],"exampleFix":"// before\nawait runCli(['wikidata', 'search', 'cat', '--limit', '500']);\n// after\nconst limit = Math.min(500, 50);\nawait runCli(['wikidata', 'search', 'cat', '--limit', String(limit)]);","handlingStrategy":"validation","validationCode":"const MAX_LIMIT = 50; // check command docs for the real cap\nconst n = Number(limit);\nif (!Number.isInteger(n) || n <= 0 || n > MAX_LIMIT) throw new Error(`limit must be 1..${MAX_LIMIT}`);\nawait runCli(['wikidata', 'search', query, '--limit', String(n)]);","typeGuard":"function isBoundedInt(v, max) { return Number.isInteger(v) && v > 0 && v <= max; }","tryCatchPattern":"try {\n    await runCli(['wikidata', 'search', query, '--limit', limit]);\n} catch (e) {\n    if (/must be <=/.test(e.message)) {\n        const cap = Number(e.message.match(/<= (\\d+)/)?.[1] ?? 50);\n        await runCli(['wikidata', 'search', query, '--limit', String(cap)]);\n    } else throw e;\n}","preventionTips":["Read the command's documented maximum before setting limits","Clamp values with Math.min(value, max) in callers","Paginate multiple requests instead of inflating one limit","Centralize limit constants so caps stay consistent"],"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"}