can1357/oh-my-pi · error

lookbackDays must be a positive integer or 'all'

Error message

lookbackDays must be a positive integer or 'all'

What it means

startScan validates the optional lookbackDays field of StartCodexSecurityCloudScanInput before creating a cloud scan configuration. The value must be a positive integer (>= 1) or the literal string 'all'; undefined (omit) is also allowed. Any other number — fractional, zero, or negative — is rejected client-side so an invalid request never reaches the cloud API.

Source

Thrown at packages/coding-agent/src/security/cloud.ts:271

	async getConfiguration(configurationId: string, signal?: AbortSignal): Promise<CodexSecurityCloudConfiguration> {
		let cursor: string | undefined;
		do {
			const page = await this.listConfigurations({ limit: 500, cursor, signal });
			const found = page.items.find(item => item.id === configurationId || item.sourceId === configurationId);
			if (found) return found;
			cursor = page.nextCursor;
		} while (cursor);
		throw new Error(`Unknown Codex Security cloud configuration: ${configurationId}`);
	}

	async startScan(input: StartCodexSecurityCloudScanInput): Promise<CodexSecurityCloudConfiguration> {
		if (
			input.lookbackDays !== undefined &&
			input.lookbackDays !== "all" &&
			(!Number.isInteger(input.lookbackDays) || input.lookbackDays < 1)
		) {
			throw new Error("lookbackDays must be a positive integer or 'all'");
		}
		const raw = await this.#request("scan_configurations", {
			method: "POST",
			signal: input.signal,
			body: accessToken => {
				const scanInput: JsonObject = {
					environment_id: input.environmentId,
					lookback_days: input.lookbackDays === "all" ? null : (input.lookbackDays ?? 30),
					notification_rules: [],
					owner_id: jwtSubject(accessToken),
					repo_id: input.repositoryId,
					repo_url: input.repositoryUrl,
					share_targets: [],
					state: "enabled",
				};
				if (input.maintainerAttackConcerns) scanInput.maintainer_attack_concerns = input.maintainerAttackConcerns;
				if (input.maintainerFocusAreas) scanInput.maintainer_focus_areas = input.maintainerFocusAreas;
				if (input.maintainerAdditionalContext)

View on GitHub (pinned to 9690622007)

Solutions

  1. Pass a positive integer: lookbackDays: 30
  2. Use the string 'all' to scan full history: lookbackDays: 'all'
  3. Omit the field entirely (undefined) to use the cloud-side default
  4. Round computed values before calling: Math.max(1, Math.floor(computedDays))

Example fix

// before
await client.startScan({ lookbackDays: (Date.now() - since) / 86400000 });
// after
const days = Math.max(1, Math.round((Date.now() - since) / 86400000));
await client.startScan({ lookbackDays: days });
Defensive patterns

Strategy: validation

Validate before calling

function isValidLookback(v: unknown): v is number | "all" | undefined {
	return v === undefined || v === "all" || (Number.isInteger(v) && (v as number) >= 1);
}
if (!isValidLookback(input.lookbackDays)) throw new TypeError("lookbackDays must be a positive integer or 'all'");

Type guard

const isLookback = (v: unknown): v is number | "all" =>
	v === "all" || (typeof v === "number" && Number.isInteger(v) && v >= 1);

Try / catch

try {
	await client.startScan(input);
} catch (err) {
	if (err instanceof Error && err.message.includes("lookbackDays")) {
		input.lookbackDays = "all"; // or surface a user-facing config error
	} else throw err;
}

Prevention

When it happens

Trigger: Calling client.startScan({ ... }) with lookbackDays set to 0, a negative number, a float like 7.5, or any non-'all' non-integer value.

Common situations: Computing lookback days via date math that yields a fractional value (e.g. ms-diff / DAY_MS without rounding); passing a config default of 0 meaning 'no limit' instead of 'all'; hand-editing a JSON config where the field becomes a string like '30'.

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/f2e78700c0c678f5. Report an issue: GitHub.