{"record":{"id":"a65d26d37997167f","repo":"jackwener/OpenCLI","slug":"steam-app-id-value-must-be-a-positive-integer","errorCode":null,"errorMessage":"steam app id \"${value}\" must be a positive integer","messagePattern":"steam app id \"(.+?)\" must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/steam/utils.js","lineNumber":46,"sourceCode":"export 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(`steam ${label} must be a positive integer`);\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`steam ${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\nexport function requireAppId(value) {\n    const s = String(value ?? '').trim();\n    if (!s) {\n        throw new ArgumentError('steam app id is required (e.g. \"620\" for Portal 2)');\n    }\n    if (!/^\\d+$/.test(s)) {\n        throw new ArgumentError(\n            `steam app id \"${value}\" must be a positive integer`,\n            'Copy the numeric id from `steam search` or the URL `store.steampowered.com/app/<id>/`.',\n        );\n    }\n    return s;\n}\n\nexport async function steamFetch(url, label) {\n    let resp;\n    try {\n        resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });\n    }\n    catch (err) {\n        throw new CommandExecutionError(\n            `${label} request failed: ${err?.message ?? err}`,\n            'Check that store.steampowered.com is reachable from this network.',\n        );\n    }","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/steam/utils.js#L28-L64","documentation":"requireAppId validates the Steam app id argument before calling Steam APIs. If the value is non-empty but is not composed entirely of digits, it throws an ArgumentError with a hint on where to find the numeric id. This prevents malformed app ids from being sent to store.steampowered.com.","triggerScenarios":"Calling any command that resolves an app via requireAppId with a value like 'portal 2', '620 ', 'abc123', '620-0', or a pasted URL slug instead of a pure numeric id like '620'.","commonSituations":"Users paste the game name or the whole store URL instead of the numeric id; scripts pass an empty-then-defaulted value containing letters; copy/paste includes invisible characters or commas (e.g. '1,234'); non-numeric store keys (e.g. 'Dota2Beta') are used.","solutions":["Pass only the numeric app id, e.g. 620 for Portal 2","Find the id via the steam search command or the URL store.steampowered.com/app/<id>/","Trim whitespace and strip commas/quotes from the value before calling","If using a name, first resolve the name to an id with a Steam search/lookup command"],"exampleFix":"// before\nrequireAppId('https://store.steampowered.com/app/620/Portal_2/')\n// after\nrequireAppId('620')","handlingStrategy":"validation","validationCode":"function isValidAppId(v) { const s = String(v ?? '').trim(); return /^\\d+$/.test(s); }\nif (!isValidAppId(input)) throw new Error('app id must be a positive integer, e.g. 620');","typeGuard":"function isAppId(v) { return typeof v === 'string' || typeof v === 'number' ? /^\\d+$/.test(String(v).trim()) : false; }","tryCatchPattern":"try { const id = requireAppId(input); } catch (e) { if (e instanceof ArgumentError) { console.error('Usage: pass a numeric Steam app id, e.g. 620'); } else throw e; }","preventionTips":["Always pass the numeric id from store.steampowered.com/app/<id>/ URLs","Trim and normalize user input before calling","Pre-resolve game names to ids via steam search","Add a regex check for ^\\d+$ in upstream scripts"],"tags":["validation","cli-argument","steam"],"backgroundTag":"invalid-cli-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}