santifer/career-ops · warning

⚠️ Skipping malformed pipe-delimited ${filename}: ${parts.l

Error message

⚠️  Skipping malformed pipe-delimited ${filename}: ${parts.length} fields

What it means

When a batch/tracker-additions file's single line starts with '|', merge-tracker.mjs parses it as a markdown table row. After stripping the leading/trailing empty cells from the split, fewer than 8 remaining fields means required data is missing, so the file is skipped with this field-count warning rather than merged with shifted columns.

Source

Thrown at merge-tracker.mjs:659

    location: untagged[0] || '',
    url: urls[0] || '',
  };
}

function parseTsvContent(content, filename) {
  content = content.trim();
  if (!content) return null;

  let parts;
  let addition;

  // Detect pipe-delimited (markdown table row)
  if (content.startsWith('|')) {
    parts = content.split('|').map(s => s.trim());
    if (parts[0] === '') parts.shift();
    if (parts[parts.length - 1] === '') parts.pop();
    if (parts.length < 8) {
      console.warn(`⚠️  Skipping malformed pipe-delimited ${filename}: ${parts.length} fields`);
      return null;
    }
    // Format: num | date | company | role | score | status | pdf | report | notes [| location]
    // Identify score vs status by content, not position, so a swapped row can't
    // merge silently (#1427).
    const resolved = resolveScoreStatus(parts[4], parts[5]);
    if (!resolved) {
      console.warn(`⚠️  Skipping ${filename}: cannot tell score from status in columns 5–6 ("${parts[4]}" | "${parts[5]}") — refusing to merge a possible column swap`);
      return null;
    }
    addition = {
      num: parseInt(parts[0]),
      date: parts[1],
      company: parts[2],
      role: parts[3],
      // Write-canonical: the tracker stores scores unbolded (verify-pipeline
      // rejects bold scores), so strip any markdown bold from the incoming cell.
      score: resolved.score.replace(/\*\*/g, '').trim(),

View on GitHub (pinned to 60398d6549)

Solutions

  1. Rewrite the row with all required columns: num, date, company, role, score, status, pdf, report, notes
  2. Prefer the tab-separated TSV format (the documented batch convention) to avoid markdown table edge cases
  3. Re-run node merge-tracker.mjs and confirm the file merges without the warning

Example fix

# before
| 042 | 2026-08-20 | Acme | SRE | Interview | 4.2/5 | [042](reports/042-acme-2026-08-20.md) |

# after
| 042 | 2026-08-20 | Acme | SRE | Interview | 4.2/5 | ✅ | [042](reports/042-acme-2026-08-20.md) | note |
Defensive patterns

Strategy: validation

Validate before calling

function pipeRowHasAllColumns(line) {
  if (!line.startsWith('|')) return true; // not pipe-format
  const parts = line.split('|').map(s => s.trim());
  if (parts[0] === '') parts.shift();
  if (parts[parts.length - 1] === '') parts.pop();
  return parts.length >= 8;
}

Prevention

When it happens

Trigger: A pipe-delimited row supplying only 7 cells — e.g. a missing pdf or report column — makes parts.length < 8 after the boundary empty cells are shifted/popped, and the addition is rejected.

Common situations: Hand-building a markdown-table-style row and forgetting the pdf ✅/❌ or report link column; a table row copied with a truncated last cell; template drift where a column was dropped.

Understand the failure class

Related errors


AI-assisted analysis of santifer/career-ops@60398d6549 (2026-08-20). Data as JSON: /api/errors/62d7374626768f76. Report an issue: GitHub.