santifer/career-ops · error
⚠️ Skipping : header labels the same column twice ( ) —…
Error message
⚠️ Skipping ${filename}: header labels the same column twice (${[...new Set(duplicates)].join(', ')}) — refusing to guess which one carries the value What it means
parseHeadedAddition() in merge-tracker.mjs resolves TSV header labels to fields via resolveTsvColumns(). If the same required/optional label appears in two columns (e.g. two 'score' headers), the value's column is undecidable, so the file is refused with this warning and nothing is merged — deliberate 'refuse to guess' behavior to avoid transposed rows.
Solutions
- Remove the duplicate header column (and its value) so each label appears once
- Check for alias spellings that map to the same field and keep only one
- Re-run merge-tracker.mjs after fixing the header
Example fix
// before num\tdate\tcompany\trole\tscore\tstatus\tpdf\treport\tscore\tnotes // after num\tdate\tcompany\trole\tscore\tstatus\tpdf\treport\tnotes
Defensive patterns
Strategy: validation
Validate before calling
const labels = headerRow.split('\t');
const dupes = labels.filter((l, i) => labels.indexOf(l) !== i);
if (dupes.length) throw new Error('Duplicate header labels: ' + dupes.join(', ')); Prevention
- Copy the canonical header template instead of writing headers by hand
- Keep one column per field — merge extra data into notes
- Verify merge-tracker.mjs output for skip warnings after each batch
When it happens
Trigger: A batch/tracker-additions/*.tsv whose header row lists the same label twice, including alias spellings that resolve to the same field (e.g. 'company' and a synonym alias both present).
Common situations: Hand-building a header row and duplicating a column; template concatenation errors; adding a synonym alias column next to the canonical one.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- ⚠️ : ignoring unrecognized header column(s)
- ⚠️ Skipping : header is missing required column(s)
- ⚠️ Non-canonical status
- ⚠️ Skipping : ambiguous extra fields [ ] — expected at most…
- ⚠️ Additions carry a URL but this tracker has no URL…
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/5b35e78c68a62bde.
Report an issue: GitHub.
Appendix: source
Thrown at merge-tracker.mjs:784
/**
* Parse a HEADED addition: a row of column labels followed by exactly one data
* row. Fields resolve by NAME, so no column order is privileged and the
* score/status pair needs no content sniffing.
*
* This is the form that has no undecidable case. `resolveScoreStatus` cannot
* order a discarded, never-scored row (`—` is both a score sentinel and a
* status meaning Discarded), so the headerless path refuses it; a header row
* answers it outright (#3517).
*
* @param {string[]} lines - Non-empty lines of the addition file.
* @param {string} filename - Source filename used in warning messages.
* @returns {object|null} Parsed tracker addition, or null when malformed.
*/
function parseHeadedAddition(lines, filename) {
const { map, missing, duplicates, unknown } = resolveTsvColumns(splitAdditionCells(lines[0]));
if (duplicates.length) {
console.warn(`⚠️ Skipping ${filename}: header labels the same column twice (${[...new Set(duplicates)].join(', ')}) — refusing to guess which one carries the value`);
return null;
}
if (missing.length) {
console.warn(`⚠️ Skipping ${filename}: header is missing required column(s): ${missing.join(', ')}`);
return null;
}
if (unknown.length) {
// Not fatal: an unrecognized label is a column this version has no meaning
// for, and dropping it loses nothing the tracker could store anyway. Say so
// rather than swallowing it, since the usual cause is a typo'd label.
console.warn(`⚠️ ${filename}: ignoring unrecognized header column(s): ${unknown.join(', ')}`);
}
const dataLines = lines.slice(1);
if (dataLines.length === 0) {
console.warn(`⚠️ Skipping ${filename}: header row with no data row`);
return null;
}View on GitHub (pinned to aac998c7ed)