can1357/oh-my-pi · error · ToolError

Limit must be a positive number

Error message

Limit must be a positive number

What it means

The glob tool validates the caller-supplied limit before scanning. It must be a finite number greater than 0; the internal DEFAULT_LIMIT is used only when limit is omitted, not when it is explicitly null/0/negative/NaN.

Source

Thrown at packages/coding-agent/src/tools/glob.ts:301

							const parsed = parseFindPattern(effectivePatterns[0] ?? ".");
							return {
								searchPath: resolveToCwd(parsed.basePath, this.session.cwd),
								globPattern: parsed.globPattern,
								hasGlob: parsed.hasGlob,
							};
						})(),
					];
			const scopePath = multiPattern?.scopePath ?? formatScopePath(targets[0].searchPath);

			for (const target of targets) {
				if (target.searchPath === "/") {
					throw new ToolError("Searching from root directory '/' is not allowed");
				}
			}

			const requestedLimit = limit ?? DEFAULT_LIMIT;
			if (!Number.isFinite(requestedLimit) || requestedLimit <= 0) {
				throw new ToolError("Limit must be a positive number");
			}
			const effectiveLimit = Math.min(MAX_LIMIT, Math.max(1, Math.floor(requestedLimit)));
			const includeHidden = hidden ?? true;
			const useGitignore = gitignore ?? true;
			const timeoutMs = this.#timeoutMs;
			const timeoutSignal = AbortSignal.timeout(timeoutMs);
			const combinedSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
			const formatMatchPath = (matchPath: string, base: string, fileType?: natives.FileType): string => {
				const hadTrailingSlash = matchPath.endsWith("/") || matchPath.endsWith("\\");
				const absolutePath = path.isAbsolute(matchPath) ? matchPath : path.resolve(base, matchPath);
				return formatPathRelativeToCwd(absolutePath, this.session.cwd, {
					trailingSlash: fileType === natives.FileType.Dir || hadTrailingSlash,
				});
			};

			const missingPathsNote =
				missingPaths.length > 0 ? `Skipped missing paths: ${missingPaths.join(", ")}` : undefined;

View on GitHub (pinned to 9690622007)

Solutions

  1. Pass a positive integer (e.g. limit: 50) or omit limit entirely to use the default
  2. Clamp/validate user-supplied limits before calling: Number.isFinite(n) && n > 0
  3. Replace NaN results from parsing with a sane default

Example fix

// before
const limit = Number(userInput); // NaN or 0 possible
await globTool.execute({ pattern, path, limit })
// after
const parsed = Number(userInput);
const limit = Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
await globTool.execute({ pattern, path, limit })
Defensive patterns

Strategy: validation

Validate before calling

function sanitizeLimit(n: number | undefined): number | undefined {
  if (n === undefined) return undefined;
  if (!Number.isFinite(n) || n <= 0) return undefined; // fall back to default
  return Math.floor(n);
}
const limit = sanitizeLimit(userLimit);

Type guard

function isValidLimit(n: unknown): n is number {
  return typeof n === "number" && Number.isFinite(n) && n > 0;
}

Try / catch

try {
  return await globTool.execute({ pattern, path, limit });
} catch (err) {
  if (err instanceof ToolError && err.message === "Limit must be a positive number") {
    return await globTool.execute({ pattern, path }); // default limit
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling execute() with limit: 0, a negative number, NaN, or Infinity (limit ?? DEFAULT_LIMIT does not replace an explicitly provided invalid value — only undefined/null).

Common situations: Computing a limit from user input without validation; propagating a NaN from a failed parseInt; JSON configs where 'limit: 0' means 'unlimited' to the caller but is rejected here.

Understand the failure class

Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — this error's family across 28 libraries.

Related errors


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