can1357/oh-my-pi · error
Invalid ${scheme}:// list limit '${limitRaw}'. Expected a po
Error message
Invalid ${scheme}:// list limit '${limitRaw}'. Expected a positive integer (max ${LIST_LIMIT_MAX}). What it means
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.
Source
Thrown at packages/coding-agent/src/internal-urls/issue-pr-protocol.ts:92
function parseListOptions(url: InternalUrl, scheme: Scheme, repo: string | undefined): ParsedList {
const stateRaw = url.searchParams.get("state");
const allowedStates: ParsedList["state"][] =
scheme === "pr" ? ["open", "closed", "merged", "all"] : ["open", "closed", "all"];
if (stateRaw !== null && !(allowedStates as string[]).includes(stateRaw)) {
// Reject instead of silently falling back to "open": a typo'd state
// would otherwise return the open list, indistinguishable from "no
// matches for the requested state".
throw new Error(`Invalid ${scheme}:// list state '${stateRaw}'. Expected one of: ${allowedStates.join(", ")}.`);
}
const state = (stateRaw ?? "open") as ParsedList["state"];
const limitRaw = url.searchParams.get("limit");
let limit = LIST_LIMIT_DEFAULT;
if (limitRaw !== null) {
const parsed = parsePositiveDecimalInt(limitRaw);
if (parsed === undefined) {
throw new Error(
`Invalid ${scheme}:// list limit '${limitRaw}'. Expected a positive integer (max ${LIST_LIMIT_MAX}).`,
);
}
limit = Math.min(parsed, LIST_LIMIT_MAX);
}
return {
kind: "list",
repo,
state,
limit,
author: url.searchParams.get("author") ?? undefined,
label: url.searchParams.get("label") ?? undefined,
};
}
function parseUrl(url: InternalUrl, scheme: Scheme): Parsed {
let host = url.rawHost || url.hostname;
const rawPath = url.rawPathname ?? url.pathname;View on GitHub (pinned to 9690622007)
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
Example fix
// before
resolve(`issue://org/repo?limit=${count ?? 'undefined'}`)
// after
const limit = Number.isInteger(count) && count > 0 ? count : 20
resolve(`issue://org/repo?limit=${limit}`) Defensive patterns
Strategy: validation
Validate before calling
function assertLimit(v: unknown): asserts v is number {
if (v !== undefined && !(typeof v === 'number' && Number.isInteger(v) && v > 0))
throw new Error(`limit must be a positive integer, got ${v}`)
} Type guard
const isValidLimit = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v) && v > 0
Prevention
- 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
When it happens
Trigger: Calling parseUrl on issue://...?limit=abc, ?limit=0, ?limit=-5, ?limit=1e3, or ?limit=10.5 — any non-positive-integer string.
Common situations: Programmatic URL construction inserting undefined as 'undefined'; locale-formatted numbers ('1,000'); assuming large limits are clamped (they are, if syntactically valid).
Related errors
- Provider delete URL must not embed an account credential
- ${destination} returned an invalid upload URL
- Destination option endpoint must be an absolute URL
- Destination option endpoint must use HTTP or HTTPS
- Destination option ${optionName} must be an absolute HTTP UR
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3118e8a588caa78a.
Report an issue: GitHub.