{"record":{"id":"3dfa85b0501703a8","repo":"santifer/career-ops","slug":"skipping-filename-header-is-missing-required-column-s","errorCode":null,"errorMessage":"⚠️  Skipping ${filename}: header is missing required column(s): ${missing.join(', ')}","messagePattern":"⚠️  Skipping (.+?): header is missing required column\\(s\\): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"merge-tracker.mjs","lineNumber":788,"sourceCode":" * score/status pair needs no content sniffing.\n *\n * This is the form that has no undecidable case. `resolveScoreStatus` cannot\n * order a discarded, never-scored row (`—` is both a score sentinel and a\n * status meaning Discarded), so the headerless path refuses it; a header row\n * answers it outright (#3517).\n *\n * @param {string[]} lines - Non-empty lines of the addition file.\n * @param {string} filename - Source filename used in warning messages.\n * @returns {object|null} Parsed tracker addition, or null when malformed.\n */\nfunction parseHeadedAddition(lines, filename) {\n  const { map, missing, duplicates, unknown } = resolveTsvColumns(splitAdditionCells(lines[0]));\n  if (duplicates.length) {\n    console.warn(`⚠️  Skipping ${filename}: header labels the same column twice (${[...new Set(duplicates)].join(', ')}) — refusing to guess which one carries the value`);\n    return null;\n  }\n  if (missing.length) {\n    console.warn(`⚠️  Skipping ${filename}: header is missing required column(s): ${missing.join(', ')}`);\n    return null;\n  }\n  if (unknown.length) {\n    // Not fatal: an unrecognized label is a column this version has no meaning\n    // for, and dropping it loses nothing the tracker could store anyway. Say so\n    // rather than swallowing it, since the usual cause is a typo'd label.\n    console.warn(`⚠️  ${filename}: ignoring unrecognized header column(s): ${unknown.join(', ')}`);\n  }\n\n  const dataLines = lines.slice(1);\n  if (dataLines.length === 0) {\n    console.warn(`⚠️  Skipping ${filename}: header row with no data row`);\n    return null;\n  }\n  if (dataLines.length > 1) {\n    // One addition per file is the contract every caller assumes (the merge\n    // loop takes one addition per TSV). Rejecting is louder than merging the\n    // first row and dropping the rest, which would lose evaluations silently.","sourceCodeStart":770,"sourceCodeEnd":806,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/merge-tracker.mjs#L770-L806","documentation":"parseHeadedAddition() validates that every REQUIRED column label (num, date, company, role, score, status, pdf, report) is present in the TSV header. If any are missing, the file is skipped entirely with this warning listing the absent labels — a malformed addition is never merged partially.","triggerScenarios":"A batch/tracker-additions/*.tsv whose header omits one or more required labels — e.g. forgetting the pdf column, or writing only a partial header row.","commonSituations":"Hand-written TSV files missing columns like pdf or report; trimmed-down headers someone assumed were optional; copy-paste that dropped a column.","solutions":["Add the missing required column(s) named in the warning to the header row and fill a value in the data row (use a sentinel like N/A for score when unscored)","Copy the header template from AGENTS.md / DATA_CONTRACT.md rather than writing it by hand","Re-run merge-tracker.mjs after fixing"],"exampleFix":"// before\nnum\\tdate\\tcompany\\trole\\tscore\\tstatus\\tnotes\n// after\nnum\\tdate\\tcompany\\trole\\tscore\\tstatus\\tpdf\\treport\\tnotes","handlingStrategy":"validation","validationCode":"const REQUIRED = ['num','date','company','role','score','status','pdf','report'];\nconst present = headerRow.split('\\t').map(s => s.trim().toLowerCase());\nconst missing = REQUIRED.filter(r => !present.includes(r));\nif (missing.length) throw new Error('Missing required columns: ' + missing.join(', '));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Start every tracker-addition file from the documented 10-label header","Include all required columns even when a value is a sentinel (N/A)","Run merge-tracker.mjs and read its warnings before considering a batch merged"],"tags":["tsv","header-validation","missing-column","tracker"],"backgroundTag":"missing-required-config-field","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}