santifer/career-ops · warning
⚠️ ${s.url} — batch reports report #${s.reportNum} but no r
Error message
⚠️ ${s.url} — batch reports report #${s.reportNum} but no reports/${s.reportNum}-*.md found; left in Pendientes. What it means
reconcile-pipeline.mjs moves processed pipeline.md entries into the done section by trusting the report numbers recorded in batch TSVs. When a TSV claims report #N but no reports/N-*.md exists, the entry is deliberately left in Pendientes (skippedNoReport) and this warning is printed -- refusing to write a done-line whose report link is dead.
Source
Thrown at reconcile-pipeline.mjs:240
const parts = body.split('|').map(s => s.trim());
const company = parts[1] || '';
const role = parts[2] || '';
const score = resolveScore(done.score, reportFile);
const pdf = resolvePdf(reportFile);
const num = parseInt(done.reportNum, 10);
const reportLink = normalizeReportLink(`[${num}](reports/${reportFile})`, dirname(PIPELINE_FILE), CAREER_OPS);
movedProcLines.push(`- [x] ${reportLink} | ${url} | ${company} | ${role} | ${score} | PDF ${pdf}`);
moved.push({ url, company, role, num, score });
procUrls.add(url);
removeIdx.add(i);
}
// ---- report & exit early if nothing changed ----
console.log('=== Reconcile pipeline.md ===');
for (const s of skippedNoReport) {
console.warn(`⚠️ ${s.url} — batch reports report #${s.reportNum} but no reports/${s.reportNum}-*.md found; left in Pendientes.`);
}
if (removeIdx.size === 0) {
console.log('✅ pipeline.md already in sync — nothing to reconcile.');
process.exit(0);
}
// ---- rebuild the file ----
const out = [];
let skipBlankAfterProc = false;
for (let i = 0; i < lines.length; i++) {
if (removeIdx.has(i)) continue;
if (skipBlankAfterProc) {
skipBlankAfterProc = false;
if (lines[i].trim() === '') continue; // drop the original blank after "## Procesadas"
}
out.push(lines[i]);
if (i === procStart && movedProcLines.length > 0) {View on GitHub (pinned to 60398d6549)
Solutions
- Locate the real report: ls reports/ | grep <number or company-slug> -- it may exist under a different number.
- Fix the TSV's report number to match the actual file, or re-run the evaluation for that URL if the report truly never landed.
- Re-run node reconcile-pipeline.mjs; the entry moves once the link resolves.
Example fix
# before: TSV claims a report that does not exist 064 2026-08-20 Acme ... [064](reports/064-acme-2026-08-20.md) ... $ ls reports/ | grep acme # -> 065-acme-2026-08-20.md # after: point the TSV at the real file and re-run reconcile 064 2026-08-20 Acme ... [064](reports/065-acme-2026-08-20.md) ...
Defensive patterns
Strategy: validation
Validate before calling
// Before reconcile, confirm every TSV's report number has a real file
import { readdirSync, readFileSync, existsSync } from 'node:fs';
const reports = new Set(readdirSync('reports'));
for (const f of readdirSync('batch/tracker-additions').filter(f => f.endsWith('.tsv'))) {
const cells = readFileSync(`batch/tracker-additions/${f}`, 'utf-8').trim().split('\t');
const num = cells[0].padStart(3, '0');
if (![...reports].some(r => r.startsWith(`${num}-`)))
console.error(`${f}: report #${num} has no reports/${num}-*.md`);
} Prevention
- Run reconcile only after the batch's reports are confirmed written (the runner prints 'Report saved: ...' per file).
- Use --report=N archiving so captures and reports share the tracked number.
- Never delete reports/ files without checking batch/tracker-additions/ and pipeline.md references first.
When it happens
Trigger: A batch worker wrote the tracker TSV but crashed before writing the report file; the report was deleted or renamed by hand; reconcile running against a different CAREER_OPS root than the one hosting reports/.
Common situations: Interrupted parallel batch runs; overzealous manual cleanup of reports/; git operations dropping untracked report files; stale batch/tracker-additions/ from an old session.
Related errors
- Invalid or blocked URL: ${rejected.reason}
- each entry needs a string "input" and "output"
- invalid format "${entryFormat}" (use: ${validFormats.join(',
- invalid reportNum "${entryReport}" (use the numeric report n
- output escapes the tracker workspace: ${entryOutput}
AI-assisted analysis of santifer/career-ops@60398d6549 (2026-08-20).
Data as JSON: /api/errors/c4acc88702c8e2f4.
Report an issue: GitHub.