santifer/career-ops · error · Error

Invalid page budget " ". Use a positive integer.

Error message

Invalid page budget "${maxPages}". Use a positive integer.

What it means

enforcePageBudget validates the maxPages option as well: it must be a positive integer (default 2). A non-integer, zero, negative, or non-numeric budget is rejected with this message before any comparison happens, so a mistyped configuration cannot silently allow or block everything.

Solutions

  1. Pass a positive integer, e.g. --max-pages=1 or maxPages: 1
  2. If the value comes from a string flag/config, coerce with parseInt/Number and validate Number.isInteger(n) && n >= 1 before calling
  3. Remember the budget cannot be disabled via 0 — trim the CV or raise the budget instead

Example fix

// before
enforcePageBudget(pageCount, { maxPages: Number(opts.maxPages) }); // '2x' -> NaN
// after
const maxPages = parseInt(opts.maxPages, 10);
if (!Number.isInteger(maxPages) || maxPages < 1) throw new Error(`--max-pages must be a positive integer, got ${opts.maxPages}`);
enforcePageBudget(pageCount, { maxPages, strictPages: opts.strictPages });
Defensive patterns

Strategy: validation

Validate before calling

const maxPages = Number.parseInt(flagValue, 10);
if (!Number.isInteger(maxPages) || maxPages < 1) {
  throw new Error(`--max-pages must be a positive integer, got "${flagValue}"`);
}
enforcePageBudget(pageCount, { maxPages, strictPages: strict });

Type guard

const isValidBudget = (n) => Number.isInteger(n) && n >= 1;

Try / catch

try {
  enforcePageBudget(pageCount, { maxPages });
} catch (err) {
  if (err.message.includes('Invalid page budget')) {
    console.error('Fix --max-pages (or config maxPages):', err.message);
    process.exit(1);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling enforcePageBudget with maxPages: 0, -1, '2', NaN, or Infinity — typically from a CLI flag like --max-pages=0 parsed as a number without validation, or a config file carrying maxPages: "two".

Common situations: Users setting a 1-page CV budget with a malformed flag value (--max-pages=one), YAML config quoting the number as a string that later fails coercion, or an off-by-one attempt to 'disable' the budget using 0.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16). Data as JSON: /api/errors/d481446dad4cbaac. Report an issue: GitHub.

Appendix: source

Thrown at generate-pdf.mjs:1024

}

/**
 * Decide whether a rendered CV fits its configured page budget.
 *
 * This is deliberately separate from rendering: page count comes from the
 * PDF Chromium actually produced, and the renderer never changes layout to
 * force content under the limit.
 *
 * @param {number} pageCount - Actual pages in the rendered PDF.
 * @param {{ maxPages?: number, strictPages?: boolean }} [options]
 * @returns {void}
 */
export function enforcePageBudget(pageCount, { maxPages = 2, strictPages = false } = {}) {
  if (!Number.isInteger(pageCount) || pageCount < 1) {
    throw new Error(`Could not determine the rendered PDF page count (received ${pageCount}).`);
  }
  if (!Number.isInteger(maxPages) || maxPages < 1) {
    throw new Error(`Invalid page budget "${maxPages}". Use a positive integer.`);
  }
  if (pageCount <= maxPages) return;

  const actualLabel = 'pages';
  const allowedLabel = maxPages === 1 ? 'page' : 'pages';
  const message =
    `CV is ${pageCount} ${actualLabel}; the allowed maximum is ${maxPages} ${allowedLabel}. ` +
    'Trim lower-priority bullets, older roles, secondary projects, or the competencies strip, then regenerate.';

  if (strictPages) {
    throw new Error(`${message} (--strict-pages requested)`);
  }

  console.warn(`⚠️  ${message} Continuing because overflow is warning-only by default; use --strict-pages to reject it.`);
}

/**
 * Read the page count from the PDF catalog's root /Pages dictionary.

View on GitHub (pinned to aac998c7ed)