santifer/career-ops · warning
#${conflict.num}: ${summary} — no automatic update
Error message
#${conflict.num}: ${summary} — no automatic update What it means
The per-conflict detail line under the manual-review header: formats each contested tracker row as '#num: StatusA (n replies) vs StatusB (m replies) -- no automatic update'. The counts tell the human how many replies support each suggestion so they can weigh majority versus recency (a later rejection often outweighs two earlier auto-acks) before deciding.
Source
Thrown at reply-watch.mjs:295
recommendations.push({
num: app.num,
company: app.company,
role: app.role,
oldStatus: app.status,
newStatus: classification.suggestedTrackerUpdate
});
}
}
});
const groupedRecommendations = groupStatusRecommendations(recommendations);
if (groupedRecommendations.conflicts.length > 0) {
console.warn('Conflicting status recommendations require manual review:');
for (const conflict of groupedRecommendations.conflicts) {
const summary = conflict.choices
.map(choice => `${choice.newStatus} (${choice.count} ${choice.count === 1 ? 'reply' : 'replies'})`)
.join(' vs ');
console.warn(` #${conflict.num}: ${summary} — no automatic update`);
}
console.log('');
}
if (groupedRecommendations.updates.length > 0) {
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)` : '';View on GitHub (pinned to 60398d6549)
Solutions
- Sort the involved replies by date and let the most recent definitive one (Rejected, Offer, Interview) win.
- Apply the chosen state explicitly: node set-status.mjs <num> <State> --note '...'.
- If the replies actually concern different roles, split them into separate tracker rows first (via TSV + merge-tracker).
Example fix
# before #42: Interview (1 reply) vs Rejected (2 replies) — no automatic update # after $ node set-status.mjs 42 Rejected --note 'final rejection dated after interview invite'
Defensive patterns
Strategy: validation
Prevention
- When reading a conflict line, weigh recency over count: the latest definitive reply (Rejected/Offer/Interview) usually reflects reality.
- Record the deciding email's date in the set-status note so the choice is auditable.
- If statuses genuinely oscillate (interview then rejection), the tracker should follow chronology, not majority.
When it happens
Trigger: Same as the parent conflict path: multiple replies for one application classified into different suggested statuses; a final-state reply (Rejected/Offer) arriving after interim ones (Responded/Interview).
Common situations: Mailbox backlogs processed at once; recruiter sequences that send an ack, an invite, and a rejection for the same req.
Related errors
- Conflicting status recommendations require manual review:
- Could not parse existing candidates file at ${candidatesPath
- Skipped #${r.num}: status changed from ${r.oldStatus} to ${r
- Skipped #${r.num}: row no longer exists in the tracker
AI-assisted analysis of santifer/career-ops@60398d6549 (2026-08-20).
Data as JSON: /api/errors/de0ef41c11ce5cd4.
Report an issue: GitHub.