santifer/career-ops · warning
Skipped #${r.num}: status changed from ${r.oldStatus} to ${r
Error message
Skipped #${r.num}: status changed from ${r.oldStatus} to ${result.conflicts.get(r.num)} during review What it means
Optimistic-concurrency guard in reply-watch's apply step: after the user answers 'y', updateTrackerStatuses() re-reads the tracker and only writes rows whose current status still equals the oldStatus captured during classification. A row that changed between review and apply (another terminal, a set-status.mjs or merge-tracker run) lands in result.conflicts and is skipped with this warning instead of clobbering the newer state.
Source
Thrown at reply-watch.mjs:319
const updates = groupedRecommendations.updates;
console.log('Suggested status updates to apply:');
updates.forEach(r => {
const count = r.count > 1 ? ` (${r.count} replies)` : '';
console.log(` #${r.num} ${r.company} (${r.role}): ${r.oldStatus} → ${r.newStatus}${count}`);
});
console.log('');
const answer = await askQuestion(`Apply recommended status updates to ${APPS_FILE}? (y/N): `);
if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
const result = await updateTrackerStatuses(updates);
for (const r of updates) {
const count = r.count > 1 ? ` (${r.count} replies)` : '';
if (result.applied.has(r.num)) {
console.log(`Updated #${r.num} to ${r.newStatus}${count}`);
} else if (result.alreadyCurrent.has(r.num)) {
console.log(`No change for #${r.num}: already ${r.newStatus}${count}`);
} else if (result.conflicts.has(r.num)) {
console.warn(`Skipped #${r.num}: status changed from ${r.oldStatus} to ${result.conflicts.get(r.num)} during review`);
} else if (result.missing.has(r.num)) {
console.warn(`Skipped #${r.num}: row no longer exists in the tracker`);
}
}
console.log('\n✅ Tracker review complete');
// Sync tracker DB if tracker.mjs exists
try {
const { execSync } = await import('child_process');
execSync('node tracker.mjs sync', { stdio: 'ignore' });
console.log('Synced database index (applications.db).');
} catch (e) {
// ignore
}
} else {
console.log('Updates skipped.');
}
}View on GitHub (pinned to 60398d6549)
Solutions
- Re-run node reply-watch.mjs -- it re-reads current statuses and re-recommends against the fresh state.
- Or set the intended state directly: node set-status.mjs <num> <State> --note '...'.
- Avoid concurrent writers: finish reply-watch before running other tracker-mutating commands.
Example fix
# before Skipped #42: status changed from Responded to Interview during review # after: re-classify against the fresh tracker $ node reply-watch.mjs # now recommends from Interview onward
Defensive patterns
Strategy: retry
Validate before calling
// Minimize the review window: capture tracker state and apply promptly const snapshot = readTrackerStatuses(); // classify + prompt user quickly // re-validate right before applying const current = readTrackerStatuses(); const safe = updates.filter(u => current.get(u.num) === u.oldStatus);
Prevention
- Do not leave reply-watch's y/N prompt open while running other tracker writes (set-status, merge-tracker, dedup).
- When the skip fires, simply re-run reply-watch — it re-recommends from the fresh state.
- Use one tracker-mutating session at a time; the file lock serializes writes but not your review time.
When it happens
Trigger: Editing applications.md or running set-status.mjs / merge-tracker.mjs in a second terminal while reply-watch's confirmation prompt is open; long pauses between classification and the y/N answer; scheduled automation firing mid-review.
Common situations: Two sessions open on the same repo; cron-scheduled merges overlapping an interactive reply-watch; review prompts left overnight.
Related errors
- Cannot verify tracker lock ownership at ${lockDir}
- Conflicting status recommendations require manual review:
- Skipped #${r.num}: row no longer exists in the tracker
- payload must include at least one of: cv, articleDigest
- payload.cv requires { section, entry }
AI-assisted analysis of santifer/career-ops@60398d6549 (2026-08-20).
Data as JSON: /api/errors/08c4fe3e1853f06d.
Report an issue: GitHub.