santifer/career-ops · warning

Sync check: active-interviews.md row for

Error message

Sync check: active-interviews.md row for "${m.company}" — "${m.role}" could not be matched to a tracker row (${m.note})

What it means

verify-pipeline.mjs reports an unmatched row: an entry in data/active-interviews.md could not be joined to any applications.md tracker row, either by an explicit `#N in tracker` Notes reference or by fuzzy Company+Role matching. The check cannot verify its status, so it warns with the matcher's note explaining why.

Solutions

  1. Add a `#N in tracker` reference to the row's Notes in active-interviews.md pointing at the correct tracker row number
  2. If no tracker row exists, create one (career-ops add / merge-tracker TSV) and link it
  3. Align the company/role spelling between the two files
  4. Re-run tracker-sync-check.mjs to confirm the row now matches

Example fix

// before (active-interviews.md Notes)
Notes: second round went well
// after
Notes: second round went well (#42 in tracker)
Defensive patterns

Strategy: validation

Validate before calling

// every active-interviews row must reference a tracker row
if (!/\#\d+ in tracker/.test(row.notes)) console.warn(`unmatched: ${row.company} — ${row.role}`);

Type guard

const hasTrackerRef = (row) => /#\d+ in tracker/.test(row.notes || '');

Prevention

When it happens

Trigger: Running `node verify-pipeline.mjs` when an active-interviews.md row lacks a `#N in tracker` note, or its company/role text differs too much from the tracker row (renamed company, reworded role title, typo).

Common situations: Logging an interview for an application never tracked; changing the role title in one file only; company name spelled differently (e.g. 'acme.io' vs 'Acme GmbH').

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of santifer/career-ops@e7abd431fc (2026-09-16). Data as JSON: /api/errors/5343dc7aa788b462. Report an issue: GitHub.

Appendix: source

Thrown at verify-pipeline.mjs:471

  // reading the exit status (CI, a cron wrapper, a pre-push hook) that is indistinguishable from
  // the invariant holding. We do not know whether the tracker is in sync; we know we failed to
  // look. The honest report is failure.
  error(`Sync check could not run — the tracker was NOT verified: ${err.message}`);
}

if (syncResult) {
  const tier1Mismatches = syncResult.mismatches.filter(m => m.resolution === 'auto-tier1');
  const tier2Mismatches = syncResult.mismatches.filter(m => m.resolution === 'needs-review-tier2');
  const unmatchedRows = syncResult.mismatches.filter(m => m.resolution === 'unmatched');

  for (const m of tier1Mismatches) {
    warn(`Sync drift (auto-resolvable): ${m.company} — ${m.role}: applications.md="${m.applicationsStatus}" vs active-interviews.md="${m.activeInterviewsStatus}" -> suggest "${m.suggestedStatus}" in ${m.staleIn} (run node tracker-sync-check.mjs for details)`);
  }
  for (const m of tier2Mismatches) {
    warn(`Sync drift (needs human review): ${m.company} — ${m.role}: applications.md="${m.applicationsStatus}" (${m.applicationsLastModified || 'no blame info'}) vs active-interviews.md="${m.activeInterviewsStatus}" (${m.activeInterviewsLastModified || 'no blame info'})`);
  }
  for (const m of unmatchedRows) {
    warn(`Sync check: active-interviews.md row for "${m.company}" — "${m.role}" could not be matched to a tracker row (${m.note})`);
  }
  if (tier1Mismatches.length === 0 && tier2Mismatches.length === 0 && unmatchedRows.length === 0) {
    ok(syncResult.summary.total > 0
      ? 'applications.md and active-interviews.md are in sync'
      : 'No active-interviews.md rows to sync-check');
  }
}

// --- Check 14: data/follow-ups.md table schema (#2971) ---
// stats.mjs (computeFollowupStats) and followup-cadence.mjs both read this table
// positionally, in the shape modes/followup.md documents, and both skip any row
// whose num/appNum cells don't parse as integers. A table written with a
// different column order therefore reports as ZERO follow-ups in both tools,
// silently — indistinguishable from a file where nothing has been logged yet.
// Follow-up compliance is exactly the number a user consults to decide whether
// their follow-ups are working, so a silent zero is actively misleading. This is
// the only place that difference is visible.
//

View on GitHub (pinned to e7abd431fc)