{"record":{"id":"d4914ce49c1bc586","repo":"santifer/career-ops","slug":"failed-to-read-profile-file-at-customprofilepath","errorCode":null,"errorMessage":"Failed to read profile file at ${customProfilePath}: ${err.message}","messagePattern":"Failed to read profile file at (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/export-ats-text.mjs","lineNumber":230,"sourceCode":" * Loads profile and CV data from file paths or default paths.\n * Fails closed if real profile configuration is missing.\n */\nexport function loadProfile(customProfilePath = null, customCvPath = null) {\n  let profileRaw = null;\n  const profileSource = customProfilePath || process.env.CAREER_OPS_PROFILE || 'config/profile.yml';\n\n  if (customProfilePath) {\n    if (!existsSync(customProfilePath)) {\n      throw new Error(`Profile configuration file not found at: ${customProfilePath}`);\n    }\n    try {\n      const content = readFileSync(customProfilePath, 'utf8');\n      profileRaw = yaml.load(content);\n      if (!profileRaw || typeof profileRaw !== 'object') {\n        throw new Error(`Invalid YAML in profile file: ${customProfilePath}`);\n      }\n    } catch (err) {\n      throw new Error(`Failed to read profile file at ${customProfilePath}: ${err.message}`);\n    }\n  } else {\n    if (!existsSync(profileSource)) {\n      throw new Error('config/profile.yml not found: fill it in first');\n    }\n    try {\n      const content = readFileSync(profileSource, 'utf8');\n      profileRaw = yaml.load(content);\n      if (!profileRaw || typeof profileRaw !== 'object') {\n        throw new Error('config/profile.yml is empty or invalid YAML: fill it in first');\n      }\n    } catch (err) {\n      throw new Error(`Failed to read profile file at ${profileSource}: ${err.message}`);\n    }\n  }\n\n  let cvData = {};\n  const cvSource = customCvPath || process.env.CAREER_OPS_CV || 'cv.md';","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/santifer/career-ops/blob/1696bec4d021768e7359f9aad6b329cba883da20/scripts/export-ats-text.mjs#L212-L248","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","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())."],"exampleFix":"// before (tab-indented YAML -> parse error)\nname:\\tAda\n\n// after\nname: Ada","handlingStrategy":"try-catch","validationCode":"import { statSync, readFileSync } from 'node:fs';\nimport yaml from 'js-yaml';\nstatSync(customProfilePath); // throws early with the true fs error\nconst raw = yaml.load(readFileSync(customProfilePath, 'utf8')); // surfaces true YAML syntax errors unwrapped","typeGuard":null,"tryCatchPattern":"try {\n  const profile = loadProfile(customProfilePath);\n} catch (e) {\n  if (e.message.startsWith('Failed to read profile file at')) {\n    const cause = e.message.split(': ').slice(1).join(': '); // original err.message\n    console.error(`Profile load failed — underlying cause: ${cause}`);\n    // route EACCES->permissions fix, YAML messages->syntax fix, ENOENT->path fix\n  } else throw e;\n}","preventionTips":["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."],"tags":["yaml","filesystem","error-wrapping","configuration"],"backgroundTag":"invalid-yaml-config","analyzedSha":"1696bec4d021768e7359f9aad6b329cba883da20","analyzedAt":"2026-09-01T19:19:23.111Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}