santifer/career-ops · error · Error

Missing required field: ${context}.${key}

Error message

Missing required field: ${context}.${key}

What it means

_require is a field-presence checker for the cover-letter JSON payload. It is called at three levels: payload must have candidate and letter; candidate must have name; letter must have role_title, opening, and profile_intro. The context prefix in the message identifies which level failed (e.g. payload.candidate, candidate.name, letter.opening).

Source

Thrown at generate-cover-letter.mjs:36

import { fileURLToPath, pathToFileURL } from "url";
import { parseArgs } from "util";
import { assertFacts } from "./verify-cv-facts.mjs";
import { resolveTemplate } from "./cv-templates.mjs";

const OUTPUT_ROOT = resolve("output");

/** Sanitize a requested output filename and keep it under the output directory. */
function safeOutputPath(raw) {
  // Derive a sanitized filename from raw string (strip path separators and dots)
  const filename = basename(raw).replace(/[^a-zA-Z0-9._-]/g, "-").replace(/\.{2,}/g, "-");
  return join(OUTPUT_ROOT, filename);
}

/** Assert that a payload object contains the required keys. */
function _require(obj, keys, context) {
  for (const key of keys) {
    if (!obj || typeof obj !== "object" || !(key in obj)) {
      throw new Error(`Missing required field: ${context}.${key}`);
    }
  }
}

/** Escape user-provided text before inserting it into generated HTML. */
function escapeHtml(text) {
  if (!text) return "";
  return String(text)
    .replace(/&/g, "&")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#39;");
}

/** Add an HTTPS scheme to a profile URL when it is omitted. */
function asUrl(value) {
  return /^https?:\/\//i.test(value) ? value : `https://${value}`;

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Inspect the payload JSON and ensure all required fields are present: payload.candidate, payload.candidate.name, payload.letter, payload.letter.role_title, payload.letter.opening, payload.letter.profile_intro.
  2. Regenerate the payload from the cover mode ensuring the JD and cv.md have enough content to fill the required fields.
  3. Validate the payload shape before passing it to generate-cover-letter.mjs.
Defensive patterns

Strategy: validation

Validate before calling

function validateCoverPayload(payload) {
  if (!payload || typeof payload !== 'object') throw new Error('payload must be an object');
  if (!payload.candidate) throw new Error('payload.candidate is required');
  if (!payload.candidate.name) throw new Error('candidate.name is required');
  if (!payload.letter) throw new Error('payload.letter is required');
  for (const key of ['role_title', 'opening', 'profile_intro']) {
    if (!payload.letter[key]) throw new Error(`letter.${key} is required`);
  }
}

Type guard

/** @param {unknown} p */
function isValidCoverPayload(p) {
  if (!p || typeof p !== 'object') return false;
  const payload = /** @type {Record<string, unknown>} */ (p);
  const c = payload.candidate;
  const l = payload.letter;
  return (
    !!c && typeof c === 'object' && 'name' in c &&
    !!l && typeof l === 'object' &&
    'role_title' in l && 'opening' in l && 'profile_intro' in l
  );
}

Prevention

When it happens

Trigger: Payload JSON is missing the top-level letter object; candidate.name is absent; letter.opening or letter.profile_intro was omitted by the mode that generated the payload; a hand-written payload forgot a required field.

Common situations: The apply or cover mode generated an incomplete payload; an agent drafted the payload and missed role_title; the JSON was hand-edited and a key was removed.

Related errors


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/111392dbe5e60ab7. Report an issue: GitHub.