santifer/career-ops · error
⚠️ Could not save report: ${err.message}
Error message
⚠️ Could not save report: ${err.message} What it means
The report-saving try in openai-eval.mjs failed, so the completed OpenAI-backed evaluation exists only on stdout — no numbered file was written under reports/. The try covers mkdirSync of reports/, reserveReportNumbers(1), and writeFileSync, so the throw can come from the filesystem (EACCES, ENOSPC, EISDIR) or from the reservation allocator. The finally still releases any reserved numbers, keeping numbering consistent. Unlike the Ollama path, a re-run costs API tokens — salvage from stdout first.
Source
Thrown at openai-eval.mjs:424
**Date:** ${today}
**Archetype:** ${archetype}
**Score:** ${score}/5
**Legitimacy:** ${legitimacy}
**PDF:** pending
**Tool:** OpenAI-compatible (${modelName} @ ${endpointHost})
---
${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
- Copy the report text from the terminal output above the warning into reports/{num}-{slug}-{date}.md manually — the API result cannot be cheaply regenerated.
- Check the basics: ls -ld reports (writable?), df -h (space?), and that no directory shares the target filename.
- If parallel workers were running, re-run after they finish — reservation contention is transient.
- Pre-flight that reports/ is writable before starting the next paid evaluation.
Example fix
// before
writeFileSync(reportPath, reportContent, 'utf-8');
// after — surface the offending path and code so the loss is diagnosable
try {
writeFileSync(reportPath, reportContent, 'utf-8');
} catch (err) {
console.error(`Report write failed at ${reportPath}: ${err.code} — copy the evaluation above into this file manually.`);
throw err;
} Defensive patterns
Strategy: validation
Validate before calling
import { accessSync, constants } from 'node:fs';
accessSync('reports', constants.W_OK); // throws EACCES BEFORE the paid API call, not after Try / catch
try {
writeFileSync(reportPath, reportContent, 'utf-8');
} catch (err) {
console.warn(`Could not save report (${err.code}): ${err.message}`);
// salvage: the full evaluation text is on stdout — tee it to a file; a re-run costs tokens
} finally {
await releaseReportNumbers(reservedNumbers, { reportsDir }); // always run
} Prevention
- Pre-flight that reports/ is writable before every paid evaluation
- Tee evaluation stdout to a log file so the report text is recoverable when the write fails
- Watch for ENOSPC on machines that also cache large model outputs
When it happens
Trigger: reports/ exists but is not writable by the current user (EACCES); disk full (ENOSPC); a directory occupies the target filename (EISDIR); reserveReportNumbers throws on sentinel/lock contention with parallel workers — all surface as this same warning.
Common situations: Running as a different user or via cron than the one owning reports/; CI disk quotas; parallel evaluation workers colliding on reservation sentinels; read-only checkouts.
Related errors
- ⚠️ Could not save report: ${err.message}
- ⚠️ Temporary HTML cleanup failed: ${err.message}
- ⚠️ Could not save HTML: ${err.message}
- ${label} escapes the tracker workspace: ${absPath}
- cannot read ${rel || '.'}: ${err.message}
AI-assisted analysis of santifer/career-ops@60398d6549 (2026-08-20).
Data as JSON: /api/errors/d7b30a6fc4d20c19.
Report an issue: GitHub.