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

  1. Pass a plain positive integer string, e.g. ?limit=50
  2. Omit ?limit to use LIST_LIMIT_DEFAULT
  3. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/3118e8a588caa78a. Report an issue: GitHub.