{"record":{"id":"a5009cb1428068fb","repo":"jackwener/OpenCLI","slug":"qianwen-history-page-size-must-be-an-integer-betwe","errorCode":null,"errorMessage":"Qianwen history page_size must be an integer between 1 and 100","messagePattern":"Qianwen history page_size must be an integer between 1 and 100","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/qwen/utils.js","lineNumber":414,"sourceCode":"    const waitFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n    const label = ${JSON.stringify(label)};\n    const button = Array.from(document.querySelectorAll('button[aria-label]'))\n      .find((node) => isVisible(node) && node.getAttribute('aria-label') === label);\n    if (!(button instanceof HTMLElement)) return { found: false };\n    const selected = button.getAttribute('aria-pressed') === 'true'\n      || /active|selected|bg-primary/.test(button.className || '');\n    if (selected === ${Boolean(enabled)}) return { found: true, changed: false, selected };\n    button.click();\n    await waitFor(300);\n    return { found: true, changed: true };\n  })()`);\n    return Boolean(result?.found);\n}\n\nexport async function getSessionListFromApi(page, limit = 30) {\n    const pageSize = Number(limit ?? 30);\n    if (!Number.isInteger(pageSize) || pageSize <= 0 || pageSize > 100) {\n        throw new CommandExecutionError('Qianwen history page_size must be an integer between 1 and 100');\n    }\n    const result = await page.evaluate(`(async () => {\n    try {\n      const utdid = (document.cookie.match(/(?:^|;\\\\s*)b-user-id=([^;]+)/)?.[1])\n        || (document.cookie.match(/(?:^|;\\\\s*)utdid=([^;]+)/)?.[1])\n        || '';\n      const query = new URLSearchParams({\n        biz_id: 'ai_qwen',\n        chat_client: 'h5',\n        device: 'pc',\n        fr: 'pc',\n        pr: 'qwen',\n        ut: utdid,\n        la: 'zh-CN',\n        tz: 'Asia/Shanghai',\n        ve: '2.4.9',\n      }).toString();\n      const res = await fetch('https://${QIANWEN_API_DOMAIN}/api/v2/session/page/list?' + query, {","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/qwen/utils.js#L396-L432","documentation":"getSessionListFromApi in clis/qwen/utils.js coerces limit via Number(limit ?? 30) and throws CommandExecutionError('Qianwen history page_size must be an integer between 1 and 100') when the value is not an integer, <= 0, or > 100. The value is sent as page_size to the Qianwen history API, which enforces a 1-100 range server-side.","triggerScenarios":"Calling with limit > 100 (e.g. 500 to 'get everything'); passing a non-integer (2.5, 'all', ''); limit resolving to 0 or negative from an empty/invalid variable; NaN from a non-numeric string.","commonSituations":"Wanting the full history and guessing a huge page_size; config files with limit: '' or null-like strings; API changes tightening the server cap; scripts multiplying values (30 * 10 = 300 -> rejected).","solutions":["Pass an integer between 1 and 100, e.g. limit = 100 (the maximum)","Fetch all pages by looping with page_size=100 and paging until fewer than 100 results return","Coerce/validate the value in your script before calling (Number.isInteger and 1-100 range)","Remove unit suffixes or invalid strings from the limit config entry"],"exampleFix":"// before\nconst sessions = await getSessionListFromApi(page, 500);\n// after\nlet sessions = [];\nfor (let offset = 0; ; offset += 100) {\n  const page_ = await getSessionListFromApi(page, 100);\n  sessions = sessions.concat(page_);\n  if (page_.length < 100) break;\n}","handlingStrategy":"validation","validationCode":"function assertPageSize(limit) {\n  const n = Number(limit ?? 30);\n  if (!Number.isInteger(n) || n <= 0 || n > 100) {\n    throw new Error(`page_size must be an integer 1-100, got: ${JSON.stringify(limit)}`);\n  }\n  return n;\n}\nassertPageSize(userLimit);","typeGuard":"const isValidPageSize = (v) => {\n  const n = Number(v);\n  return Number.isInteger(n) && n >= 1 && n <= 100;\n};","tryCatchPattern":"try {\n  const sessions = await getSessionListFromApi(page, limit);\n} catch (e) {\n  if (/page_size must be an integer between 1 and 100/.test(e.message)) {\n    console.warn('Clamping page_size to 100 and retrying');\n    return getSessionListFromApi(page, Math.min(100, Math.max(1, Number(limit) || 30)));\n  } else throw e;\n}","preventionTips":["Cap page_size at 100 — that is the API maximum","Paginate (loop with page_size=100) instead of requesting one huge page","Sanitize config values: reject empty strings and non-numeric entries before calling","Reuse one validated clamp helper wherever limit/page_size is passed"],"tags":["validation","pagination","api-limits"],"backgroundTag":"invalid-parameter-range","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}