{"record":{"id":"3118e8a588caa78a","repo":"can1357/oh-my-pi","slug":"invalid-scheme-list-limit-limitraw-exp","errorCode":null,"errorMessage":"Invalid ${scheme}:// list limit '${limitRaw}'. Expected a positive integer (max ${LIST_LIMIT_MAX}).","messagePattern":"Invalid (.+?):// list limit '(.+?)'\\. Expected a positive integer \\(max (.+?)\\)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/issue-pr-protocol.ts","lineNumber":92,"sourceCode":"\nfunction parseListOptions(url: InternalUrl, scheme: Scheme, repo: string | undefined): ParsedList {\n\tconst stateRaw = url.searchParams.get(\"state\");\n\tconst allowedStates: ParsedList[\"state\"][] =\n\t\tscheme === \"pr\" ? [\"open\", \"closed\", \"merged\", \"all\"] : [\"open\", \"closed\", \"all\"];\n\tif (stateRaw !== null && !(allowedStates as string[]).includes(stateRaw)) {\n\t\t// Reject instead of silently falling back to \"open\": a typo'd state\n\t\t// would otherwise return the open list, indistinguishable from \"no\n\t\t// matches for the requested state\".\n\t\tthrow new Error(`Invalid ${scheme}:// list state '${stateRaw}'. Expected one of: ${allowedStates.join(\", \")}.`);\n\t}\n\tconst state = (stateRaw ?? \"open\") as ParsedList[\"state\"];\n\n\tconst limitRaw = url.searchParams.get(\"limit\");\n\tlet limit = LIST_LIMIT_DEFAULT;\n\tif (limitRaw !== null) {\n\t\tconst parsed = parsePositiveDecimalInt(limitRaw);\n\t\tif (parsed === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid ${scheme}:// list limit '${limitRaw}'. Expected a positive integer (max ${LIST_LIMIT_MAX}).`,\n\t\t\t);\n\t\t}\n\t\tlimit = Math.min(parsed, LIST_LIMIT_MAX);\n\t}\n\treturn {\n\t\tkind: \"list\",\n\t\trepo,\n\t\tstate,\n\t\tlimit,\n\t\tauthor: url.searchParams.get(\"author\") ?? undefined,\n\t\tlabel: url.searchParams.get(\"label\") ?? undefined,\n\t};\n}\n\nfunction parseUrl(url: InternalUrl, scheme: Scheme): Parsed {\n\tlet host = url.rawHost || url.hostname;\n\tconst rawPath = url.rawPathname ?? url.pathname;","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/issue-pr-protocol.ts#L74-L110","documentation":"The ?limit= parameter on issue:// and pr:// list URLs must parse as a positive decimal integer (validated by parsePositiveDecimalInt); anything else throws with the max allowed (LIST_LIMIT_MAX). Valid values are capped with Math.min to the max rather than erroring.","triggerScenarios":"Calling parseUrl on issue://...?limit=abc, ?limit=0, ?limit=-5, ?limit=1e3, or ?limit=10.5 — any non-positive-integer string.","commonSituations":"Programmatic URL construction inserting undefined as 'undefined'; locale-formatted numbers ('1,000'); assuming large limits are clamped (they are, if syntactically valid).","solutions":["Pass a plain positive integer string, e.g. ?limit=50","Omit ?limit to use LIST_LIMIT_DEFAULT","Clamp your own value in code before building the URL; values above LIST_LIMIT_MAX are clamped automatically if valid"],"exampleFix":"// before\nresolve(`issue://org/repo?limit=${count ?? 'undefined'}`)\n// after\nconst limit = Number.isInteger(count) && count > 0 ? count : 20\nresolve(`issue://org/repo?limit=${limit}`)","handlingStrategy":"validation","validationCode":"function assertLimit(v: unknown): asserts v is number {\n  if (v !== undefined && !(typeof v === 'number' && Number.isInteger(v) && v > 0))\n    throw new Error(`limit must be a positive integer, got ${v}`)\n}","typeGuard":"const isValidLimit = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isInteger(v) && v > 0","tryCatchPattern":null,"preventionTips":["Coerce numeric options to integers before URL interpolation","Guard template strings against undefined/null leaking into query params","Omit ?limit rather than emitting an empty or placeholder value"],"tags":["validation","query-param","url"],"backgroundTag":"invalid-query-parameter","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}