thedotmack/claude-mem · error · Error

projection maxPages must be a positive safe integer

Error message

projection maxPages must be a positive safe integer

What it means

drainProjection validates dependencies.maxPages before draining. maxPages bounds how many pages of authoritative ops one drain may fetch, so a lagging user cannot monopolize a cron request or hold the per-user projection lease indefinitely. The error fires when a caller supplies an explicitly provided maxPages that is not a positive safe integer (0, negative, fractional, NaN, or Infinity) — an invalid dependency-injection input at the drain boundary, not a projection/runtime failure.

Solutions

  1. Pass maxPages as a positive safe integer, or omit it entirely to use the caller's default page budget
  2. Clamp/round caller-supplied page counts before constructing ProjectionDrainDependencies
  3. Align test and scheduled-repair callers with the REPAIR_DRAIN_MAX_PAGES-style positive-integer convention
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at workers/sync-hub/src/index.ts:620 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/89fba5b4892534f9. Report an issue: GitHub.

Appendix: source

Thrown at workers/sync-hub/src/index.ts:620

function projectionNow(dependencies: ProjectionDrainDependencies): number | undefined {
	return dependencies.now?.();
}

/**
 * Drain one user's authoritative Hub checkpoint through targetSeq. The DO
 * only leases/pages/CAS-advances; all outbound I/O remains in this Worker.
 */
export async function drainProjection(
	env: Env,
	userId: string,
	targetSeq: string,
	dependencies: ProjectionDrainDependencies = {},
): Promise<DrainResult> {
	if (
		dependencies.maxPages !== undefined
		&& (!Number.isSafeInteger(dependencies.maxPages) || dependencies.maxPages < 1)
	) {
		throw new Error("projection maxPages must be a positive safe integer");
	}
	const stub = env.SYNC_HUB.getByName(userId);
	let state = await stub.getProjectionState();
	if (decimalAtLeast(state.projected_seq, targetSeq)) {
		return { ok: true, projectedSeq: state.projected_seq };
	}
	if (!env.INTERNAL_PROJECTOR_URL || !env.CMEM_INTERNAL_PROJECTOR_SECRET) {
		return {
			ok: false,
			error: "projection_not_configured",
			projectedSeq: state.projected_seq,
			httpStatus: 503,
			retryable: true,
		};
	}
	const acquiredAt = projectionNow(dependencies);
	const lease = acquiredAt === undefined
		? await stub.acquireProjectionLease(targetSeq)

View on GitHub (pinned to d8bc9755e7)