santifer/career-ops · error
⚠️ Could not save HTML
Error message
⚠️ Could not save HTML: ${err.message} What it means
Fatal-path warning in openai-tailor.mjs: the try block that generates and writes the tailored CV HTML to output/ failed, so the script logs err.message and calls process.exit(1). No HTML file is produced and the suggested generate-pdf.mjs next step cannot run.
Solutions
- Create the output directory: mkdir -p output
- Check the err.message for EACCES/ENOSPC and fix permissions/disk space
- Re-run the tailoring command after fixing
- Ensure the company slug/name sanitized path is not excessively long
Example fix
// before
catch (err) {
console.warn(`⚠️ Could not save HTML: ${err.message}`);
process.exit(1);
}
// after
mkdirSync(PATHS.output, { recursive: true }); // before the write, upstream of the catch Defensive patterns
Strategy: validation
Validate before calling
import { mkdirSync, accessSync, constants, statfsSync } from 'fs';
mkdirSync(PATHS.output, { recursive: true });
accessSync(PATHS.output, constants.W_OK);
if (statfsSync(PATHS.output).bavail === 0) throw new Error('disk full'); Type guard
function isWritableDir(p) { try { accessSync(p, constants.W_OK); return statSync(p).isDirectory(); } catch { return false; } } Try / catch
try { writeFileSync(htmlPath, html); } catch (err) { console.warn(`⚠️ Could not save HTML: ${err.message}`); process.exit(1); } Prevention
- Create output/ before generating CVs (it is gitignored and not auto-created)
- Monitor disk usage on machines used for batch CV generation
- Keep sanitized slugs short to avoid filesystem filename-length limits
When it happens
Trigger: writeFileSync to output/{cv-*.html} fails: output/ directory missing, EACCES/EPERM on the file, ENOSPC, or the path derived from candidateName/companySlug is invalid.
Common situations: Fresh clone without output/ (gitignored and not auto-created); read-only CI workspace; disk full; extremely long company slug exceeding filename limits.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- apify: JD cache write failed for
- ⚠️ Could not release report reservation
- ⚠️ Could not release report reservation
- ⚠️ Could not save report
- ⚠️ Could not save report
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/3c886e885f549506.
Report an issue: GitHub.
Appendix: source
Thrown at openai-tailor.mjs:349
}
candidateName = candidateName
.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
const filename = `cv-${candidateName}-${companySlug}.html`;
const htmlPath = join(PATHS.output, filename);
writeFileSync(htmlPath, tailoredHtml, 'utf-8');
console.log(`\n✅ Tailored HTML saved: ${htmlPath}`);
// Print next steps
const pdfFilename = `cv-${candidateName}-${companySlug}-${roleSlug}-${new Date().toISOString().split('T')[0]}.pdf`;
const reportNumMatch = reportFilename.match(/^(\d+)-/);
const reportNum = reportNumMatch ? reportNumMatch[1] : '001';
console.log(`\n📄 Next step (generate PDF):\n node generate-pdf.mjs output/${filename} output/${pdfFilename} --format=letter --report=${reportNum}\n`);
} catch (err) {
console.warn(`⚠️ Could not save HTML: ${err.message}`);
process.exit(1);
}
View on GitHub (pinned to aac998c7ed)