santifer/career-ops · warning

⚠️ Could not release report reservation: ${err.message}

Error message

⚠️   Could not release report reservation: ${err.message}

What it means

The finally-block call to releaseReportNumbers threw while trying to remove this run's reservation sentinels from reports/. The reserved numbers therefore still look occupied and the next reservation skips past them. By design the allocator garbage-collects stale sentinels after 4 hours, so the leak self-heals; report numbers may simply gap in the meantime.

Source

Thrown at openai-eval.mjs:430

---

${evaluationText.replace(/---SCORE_SUMMARY---[\s\S]*?---END_SUMMARY---/, '').trim()}
`;

    writeFileSync(reportPath, reportContent, 'utf-8');
    console.log(`\n✅  Report saved: reports/${filename}`);

    console.log(`\n📊  Tracker entry (add to data/applications.md):`);
    console.log(`    | ${num} | ${today} | ${company} | ${role} | ${score}/5 | Evaluated | ❌ | [${num}](reports/${filename}) |`);
  } catch (err) {
    console.warn(`⚠️   Could not save report: ${err.message}`);
  } finally {
    if (reservedNumbers.length > 0) {
      try {
        await releaseReportNumbers(reservedNumbers, { reportsDir: PATHS.reports });
      } catch (err) {
        console.warn(`⚠️   Could not release report reservation: ${err.message}`);
      }
    }
  }
}

console.log('\n' + '─'.repeat(66));
console.log(`  Score: ${score}/5  |  Archetype: ${archetype}  |  Legitimacy: ${legitimacy}`);
console.log('─'.repeat(66) + '\n');

console.log(formatBreakdown(tracker, modelName, 'openai'));

View on GitHub (pinned to 60398d6549)

Solutions

  1. Do nothing — the 4-hour stale-sentinel GC reclaims the numbers automatically.
  2. To reclaim immediately, delete the stale sentinel files for your numbers under reports/ and verify with node reserve-report-num.mjs.
  3. Check reports/ writability if the warning repeats across runs.
Defensive patterns

Strategy: retry

Validate before calling

import { readdirSync } from 'node:fs';
const numbersStillTaken = (dir, nums) =>
  nums.some((n) => readdirSync(dir).some((f) => f.startsWith(String(n).padStart(3, '0'))));
// after the 4h GC window, a dry `node reserve-report-num.mjs --count 1` also proves the slot freed

Try / catch

try {
  await releaseReportNumbers(reservedNumbers, { reportsDir: PATHS.reports });
} catch (err) {
  console.warn(`Could not release report reservation: ${err.message}`);
  // accept the 4h stale-sentinel GC rather than crashing — gaps in numbering are harmless
}

Prevention

When it happens

Trigger: Deleting the sentinel files fails (EACCES on reports/, ENOENT when another worker's GC removed them first); a parallel worker's reservation collision aborts the release mid-way.

Common situations: Parallel eval workers using the documented reserve-first fan-out; permission changes mid-run; someone pruning reports/ while evaluations run.

Related errors


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