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

  1. Sort the involved replies by date and let the most recent definitive one (Rejected, Offer, Interview) win.
  2. Apply the chosen state explicitly: node set-status.mjs <num> <State> --note '...'.
  3. 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 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


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