santifer/career-ops · warning
#${e.num}: Score has markdown bold: "${e.score}"
Error message
#${e.num}: Score has markdown bold: "${e.score}" What it means
verify-pipeline.mjs check 7 flags tracker score cells containing markdown bold ('**'). The canonical rules forbid bold (and dates or extra text) in status/score fields because downstream parsers (tracker-parse.mjs, merge-tracker's score-column detection) match on the plain 'X.X/5' pattern; bold usually creeps in when a row is hand-edited from rendered markdown or a score is pasted from a rendered report.
Source
Thrown at verify-pipeline.mjs:224
}
if (badRows === 0) ok('All rows properly formatted');
// --- Check 6: Pending TSVs ---
let pendingTsvs = 0;
if (existsSync(ADDITIONS_DIR)) {
const files = readdirSync(ADDITIONS_DIR).filter(f => f.endsWith('.tsv'));
pendingTsvs = files.length;
if (pendingTsvs > 0) {
warn(`${pendingTsvs} pending TSVs in tracker-additions/ (not merged)`);
}
}
if (pendingTsvs === 0) ok('No pending TSVs');
// --- Check 7: Bold in scores ---
let boldScores = 0;
for (const e of entries) {
if (e.score.includes('**')) {
warn(`#${e.num}: Score has markdown bold: "${e.score}"`);
boldScores++;
}
}
if (boldScores === 0) ok('No bold in scores');
// --- Check 8: Stale report-number sentinels (GC) ---
// reserve-report-num.mjs drops NNN-RESERVED.md files in reports/ when a
// number is claimed. If the process crashed before writing the real report
// and deleting the sentinel it will linger. Sentinels older than 4 h are
// stale; remove them here so they don't skew the next slot allocation.
const SENTINEL_MAX_AGE_MS = 4 * 60 * 60 * 1000;
let staleSentinels = 0;
if (existsSync(REPORTS_DIR)) {
const now = Date.now();
for (const name of readdirSync(REPORTS_DIR)) {
if (!name.endsWith('-RESERVED.md')) continue;
const full = join(REPORTS_DIR, name);
try {View on GitHub (pinned to 60398d6549)
Solutions
- Edit the flagged row and strip '**' from the score cell, leaving exactly '4.2/5' (or a recognized sentinel like 'N/A').
- Stop hand-editing: use node set-status.mjs for status changes and TSV + node merge-tracker.mjs for additions.
- Run node normalize-statuses.mjs to sweep related formatting drift.
Example fix
# before | 42 | 2026-08-20 | Acme | ML Engineer | **4.5/5** | Applied | ... | # after | 42 | 2026-08-20 | Acme | ML Engineer | 4.5/5 | Applied | ... |
Defensive patterns
Strategy: validation
Validate before calling
// Scrub bold from a score cell before it reaches the tracker
const clean = raw.replace(/\*\*/g, '').trim();
if (!isValidScoreCell(clean)) throw new Error(`unrecognized score format: ${raw}`); Type guard
// Predicate for a clean score cell (X.X/5 or a recognized sentinel)
function isValidScoreCell(score) {
return /^\d\.\d\/5$/.test(score) || ['N/A', '—', '-'].includes(score);
} Prevention
- Never hand-edit applications.md cells by pasting from rendered markdown; type the plain value.
- Route all tracker writes through TSV + merge-tracker.mjs and status changes through set-status.mjs.
- Run node verify-pipeline.mjs after manual edits; fix flagged rows with a plain 'X.X/5' cell.
When it happens
Trigger: Hand-editing applications.md after copying text from a rendered (HTML/PDF) report or CV; tooling that writes '**4.5/5**'; markdown editors auto-bolding emphasized numbers.
Common situations: Manual table maintenance instead of the TSV+merge path; pasting from GitHub-rendered pages; over-eager editor formatting.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Sync check could not run: ${err.message}
- Possible duplicates: ${group.map(e => `#${e.num}`).join(', '
- ${pendingTsvs} pending TSVs in tracker-additions/ (not merge
- Removed stale reservation sentinel: ${name}
AI-assisted analysis of santifer/career-ops@60398d6549 (2026-08-20).
Data as JSON: /api/errors/50512dba3e4a2c1b.
Report an issue: GitHub.