santifer/career-ops · warning
Sync check could not run: ${err.message}
Error message
Sync check could not run: ${err.message} What it means
verify-pipeline.mjs's health check 13 delegates to tracker-sync-check.mjs's exported checkTrackerSync(); that call threw before producing a result. In practice this means its inputs — data/applications.md and data/active-interviews.md — are missing or do not contain the expected markdown tables (never created, renamed, or emptied by a bad merge). The rest of verify-pipeline still runs; you just get no drift report for this check.
Source
Thrown at verify-pipeline.mjs:446
for (const [num, group] of numGroups) {
if (group.length > 1) {
error(`Duplicate tracker number #${num} used by ${group.length} rows: ${group.map(e => `${e.company} — ${e.role}`).join(' | ')}`);
dupeNums++;
}
}
if (dupeNums === 0) ok('No duplicate tracker numbers');
// --- Check 13: applications.md <-> active-interviews.md status sync (#1504) ---
// Delegates to tracker-sync-check.mjs's exported checkTrackerSync() rather than
// re-implementing the matching/two-tier resolution logic here or shelling out
// to a second process. Read-only: this only surfaces drift, it does not write
// a fix (tracker-sync-check.mjs is intentionally reporting-only for now — see
// its module header).
let syncResult;
try {
syncResult = checkTrackerSync({ appsFile: APPS_FILE });
} catch (err) {
warn(`Sync check could not run: ${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 > 0View on GitHub (pinned to 60398d6549)
Solutions
- Run node tracker-sync-check.mjs standalone — its direct error pinpoints the file it choked on.
- Ensure data/active-interviews.md exists with the documented table header; same for data/applications.md.
- Re-run node verify-pipeline.mjs and confirm check 13 now reports instead of warning.
Example fix
# before — checkTrackerSync throws because active-interviews.md is missing # after — create the file with the expected header, then re-run cat > data/active-interviews.md <<'EOF' # Active Interviews | Company | Role | Round | Status | Last Update | Notes | |---------|------|-------|--------|-------------|-------| EOF node verify-pipeline.mjs
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync, readFileSync } from 'node:fs';
const tableReady = (p) => existsSync(p) && /^\|.*\|/m.test(readFileSync(p, 'utf-8'));
if (!tableReady('data/applications.md') || !tableReady('data/active-interviews.md')) {
console.warn('sync-check inputs missing or unparsed — run node tracker-sync-check.mjs for details');
} Try / catch
try {
syncResult = checkTrackerSync({ appsFile: APPS_FILE });
} catch (err) {
warn(`Sync check could not run: ${err.message}`);
} // degrade a single check, never the whole health report Prevention
- Keep both tracker files present with valid table headers, even when empty
- Run tracker-sync-check.mjs standalone first when verify-pipeline reports this
- Treat a missing sync check as unknown state, not as 'no drift'
When it happens
Trigger: data/active-interviews.md absent (fresh install with no interviews tracked yet); the file exists but has no table header to parse; a tracker file renamed during reorganization; a conflict resolved by emptying the file.
Common situations: New setups before any interview tracking; repo reorganizations renaming tracker files; merge conflicts resolved by truncation.
Related errors
- payload.articleDigest requires a non-empty dedupKey (used fo
- Application answer state must be one of: ${[...VALID_STATES]
- Application Answers section has ${skipped.length} unreadable
- ⚠️ ${label} not found: ${path}
- Possible duplicates: ${group.map(e => `#${e.num}`).join(', '
AI-assisted analysis of santifer/career-ops@60398d6549 (2026-08-20).
Data as JSON: /api/errors/94dff5cb757f4633.
Report an issue: GitHub.