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, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
/** 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
- 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.
- Regenerate the payload from the cover mode ensuring the JD and cv.md have enough content to fill the required fields.
- 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
- Validate the payload JSON shape before passing to generate-cover-letter.mjs.
- Ensure the mode that generates the payload fills all required fields.
- Use a JSON schema or the type guard above at the boundary.
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
- --${name} is required
- Unresolved placeholders: ${[...unresolved].join(', ')}
- payload must include at least one of: cv, articleDigest
- payload.cv requires { section, entry }
- payload.cv requires a non-empty dedupKey (used for dedup/ide
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/111392dbe5e60ab7.
Report an issue: GitHub.