santifer/career-ops · error · Error
Failed to read profile file at ${customProfilePath}: ${err.m
Error message
Failed to read profile file at ${customProfilePath}: ${err.message} What it means
The try/catch around reading and parsing the explicitly supplied profile file converts any failure — fs read errors (ENOENT, EACCES, EISDIR) and the nested Invalid-YAML error 304 — into this single wrapped error. The original cause is preserved in err.message appended after the path. It exists so callers get one consistent message for 'your custom profile could not be loaded'.
Source
Thrown at scripts/export-ats-text.mjs:230
* Loads profile and CV data from file paths or default paths.
* Fails closed if real profile configuration is missing.
*/
export function loadProfile(customProfilePath = null, customCvPath = null) {
let profileRaw = null;
const profileSource = customProfilePath || process.env.CAREER_OPS_PROFILE || 'config/profile.yml';
if (customProfilePath) {
if (!existsSync(customProfilePath)) {
throw new Error(`Profile configuration file not found at: ${customProfilePath}`);
}
try {
const content = readFileSync(customProfilePath, 'utf8');
profileRaw = yaml.load(content);
if (!profileRaw || typeof profileRaw !== 'object') {
throw new Error(`Invalid YAML in profile file: ${customProfilePath}`);
}
} catch (err) {
throw new Error(`Failed to read profile file at ${customProfilePath}: ${err.message}`);
}
} else {
if (!existsSync(profileSource)) {
throw new Error('config/profile.yml not found: fill it in first');
}
try {
const content = readFileSync(profileSource, 'utf8');
profileRaw = yaml.load(content);
if (!profileRaw || typeof profileRaw !== 'object') {
throw new Error('config/profile.yml is empty or invalid YAML: fill it in first');
}
} catch (err) {
throw new Error(`Failed to read profile file at ${profileSource}: ${err.message}`);
}
}
let cvData = {};
const cvSource = customCvPath || process.env.CAREER_OPS_CV || 'cv.md';View on GitHub (pinned to 1696bec4d0)
Solutions
- Read the `: ${err.message}` suffix — it names the real cause (ENOENT/EACCES/YAML syntax) and fix that underlying problem.
- Fix YAML syntax: replace tabs with spaces, close quotes/brackets, ensure `key: value` form; test with `node -e "console.log(require('js-yaml').load(require('fs').readFileSync(p,'utf8')))"`.
- Check file permissions and that the path is a regular readable file (fs.statSync(p).isFile()).
Example fix
// before (tab-indented YAML -> parse error) name:\tAda // after name: Ada
Defensive patterns
Strategy: try-catch
Validate before calling
import { statSync, readFileSync } from 'node:fs';
import yaml from 'js-yaml';
statSync(customProfilePath); // throws early with the true fs error
const raw = yaml.load(readFileSync(customProfilePath, 'utf8')); // surfaces true YAML syntax errors unwrapped Try / catch
try {
const profile = loadProfile(customProfilePath);
} catch (e) {
if (e.message.startsWith('Failed to read profile file at')) {
const cause = e.message.split(': ').slice(1).join(': '); // original err.message
console.error(`Profile load failed — underlying cause: ${cause}`);
// route EACCES->permissions fix, YAML messages->syntax fix, ENOENT->path fix
} else throw e;
} Prevention
- Always read the appended cause after the last ': ' — it distinguishes EACCES (permissions), EISDIR (wrong path type), and js-yaml syntax errors.
- Validate YAML with js-yaml directly before calling loadProfile so syntax errors surface unwrapped.
- Keep profile files user-readable (chmod 600 is fine; 000 is not) and never pass a directory path.
When it happens
Trigger: readFileSync(customProfilePath) throws (permission denied, path is a directory, file vanished between existsSync and read) OR yaml.load throws a syntax error OR the nested `Invalid YAML` error is raised — all funnel into this rethrow.
Common situations: Profile file unreadable due to file permissions (chmod 000); passing a directory instead of a file; YAML syntax mistakes (tabs for indentation, unbalanced quotes); the file being a symlink to a missing target; race where another process deletes the file.
Related errors
- Failed to read profile file at ${profileSource}: ${err.messa
- arbeitsagentur: entry "${entry.name || '(unnamed)'}" has no
- wttj: the WTTJ board is global — configure explicit searches
- Profile configuration file not found at: ${customProfilePath
- Invalid YAML in profile file: ${customProfilePath}
AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01).
Data as JSON: /api/errors/d4914ce49c1bc586.
Report an issue: GitHub.