santifer/career-ops · warning
⚠️ Failed to sync PDF flags: ${e.message}
Error message
⚠️ Failed to sync PDF flags: ${e.message} What it means
After a successful merge (tracker lock already released), merge-tracker.mjs runs sync-pdf-flags.mjs as a child process via execFileSync('node', ...) to reconcile the tracker's PDF ✅/❌ flags against files in output/. If that child exits non-zero or cannot spawn, the error is caught and downgraded to a warning so the completed merge is not rolled back -- but PDF flags may be stale until the next successful sync.
Source
Thrown at merge-tracker.mjs:1372
// is written.
if (!existsSync(MERGED_DIR)) mkdirSync(MERGED_DIR, { recursive: true });
const archivable = tsvFiles.filter(f => !failedAdditions.includes(f));
for (const file of archivable) {
renameSync(join(ADDITIONS_DIR, file), join(MERGED_DIR, file));
}
console.log(`\n✅ Moved ${archivable.length} TSVs to merged/`);
}
console.log(`\n📊 Summary: +${added} added, 🔄${updated} updated, ⏭️${skipped} skipped${failedAdditions.length ? `, ❌${failedAdditions.length} NOT merged` : ''}`);
if (DRY_RUN) console.log('(dry-run — no changes written)');
trackerLock.release();
// Sync PDF flags (idempotent; uses its own lock/transaction)
if (!DRY_RUN) {
try {
execFileSync('node', [join(CAREER_OPS, 'sync-pdf-flags.mjs')], { stdio: 'inherit' });
} catch (e) {
console.warn(`⚠️ Failed to sync PDF flags: ${e.message}`);
}
}
// Optional verify
if (VERIFY && !DRY_RUN) {
console.log('\n--- Running verification ---');
try {
execFileSync('node', [join(CAREER_OPS, 'verify-pipeline.mjs')], { stdio: 'inherit' });
} catch (e) {
process.exit(1);
}
}
// Any addition that could not be applied fails the run. The TSVs stay in the
// additions dir, so re-running after the tracker is repaired merges them once.
if (failedAdditions.length > 0) {
console.error(
`\n❌ ${failedAdditions.length} addition(s) were NOT merged and were left in ${ADDITIONS_DIR}: ` +View on GitHub (pinned to 60398d6549)
Solutions
- Run node sync-pdf-flags.mjs manually in the repo root and read the real error message it prints.
- Confirm 'node -v' works in the same shell/environment that ran merge-tracker.
- Fix the underlying cause (permissions, output/ state), then re-run node merge-tracker.mjs or just the sync -- both are idempotent.
Example fix
# before: only seeing the downgraded warning ⚠️ Failed to sync PDF flags: spawn node ENOENT # after: reproduce with full output and fix PATH $ node -v || export PATH="$HOME/.nvm/versions/node/$(cat .nvmrc)/bin:$PATH" $ node sync-pdf-flags.mjs # shows the actual failure
Defensive patterns
Strategy: retry
Validate before calling
// Before merge, confirm the sync child can run in this environment
import { existsSync } from 'node:fs';
import { execFileSync } from 'node:child_process';
if (!existsSync('sync-pdf-flags.mjs')) throw new Error('sync-pdf-flags.mjs missing from checkout');
execFileSync('node', ['-v'], { stdio: 'ignore' }); // fails fast if node is unresolvable Try / catch
// After merge: if the auto-sync warned, re-run it manually and surface the real error
try {
execFileSync('node', ['sync-pdf-flags.mjs'], { stdio: 'inherit' });
} catch (e) {
console.error(`PDF flag sync failed (${e.status ?? e.message}) — run 'node sync-pdf-flags.mjs' to see the cause`);
} Prevention
- Run merge-tracker and its sync in an environment where plain 'node' resolves (no PATH-shim-only shells).
- Treat the merge summary line as incomplete until PDF flags have synced once successfully.
- Both merge and sync are idempotent — prefer re-running over hand-editing ✅/❌ flags.
When it happens
Trigger: sync-pdf-flags.mjs crashing on a corrupt/locked tracker or unreadable output/ directory; 'node' not resolvable from the merge-tracker process environment (PATH shims, tman wrappers); CAREER_OPS pointing at a checkout where sync-pdf-flags.mjs is missing or not executable.
Common situations: PATH-shim environments that reroute node; a repo updated mid-session leaving script mismatch; permission or disk errors in output/; concurrent process holding sync-pdf-flags' own lock/transaction.
Related errors
- openai-eval.mjs exited ${res.status}: ${(res.stderr || '').s
- ⚠️ Report saved, but could not merge tracker addition into
- ⚠️ Tracker #${addition.num} already used; assigning #${entr
- ${pendingTsvs} pending TSVs in tracker-additions/ (not merge
AI-assisted analysis of santifer/career-ops@60398d6549 (2026-08-20).
Data as JSON: /api/errors/8cff5aa6aca35dc8.
Report an issue: GitHub.