santifer/career-ops · error · Error

Profile configuration file not found at: ${customProfilePath

Error message

Profile configuration file not found at: ${customProfilePath}

What it means

loadProfile in scripts/export-ats-text.mjs resolves the profile from, in order, an explicit customProfilePath argument, CAREER_OPS_PROFILE, or config/profile.yml. When the caller passes an explicit customProfilePath, the function requires that exact file to exist and fails closed with this message otherwise. Unlike the default path, a missing explicit path is treated as a caller mistake, not an uninitialized setup.

Source

Thrown at scripts/export-ats-text.mjs:221

    education = raw.education;
  } else if (Array.isArray(cvData.education) && cvData.education.length > 0) {
    education = cvData.education;
  }

  return { name, email, phone, location, linkedin, summary, experience, education, skills };
}

/**
 * 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') {

View on GitHub (pinned to 1696bec4d0)

Solutions

  1. Check the path with fs.existsSync(customProfilePath) and correct the typo or pass an absolute path (path.resolve).
  2. Run the script from the repository root, or make the path absolute relative to the repo root instead of the process cwd.
  3. If the profile was meant to be the default, drop the argument and let it fall back to CAREER_OPS_PROFILE / config/profile.yml.
  4. In CI, ensure the personal profile file is present (secret/artifact step) before invoking the exporter.

Example fix

// before
loadProfile('config/my-profile.yml'); // run from another cwd

// after
import path from 'node:path';
const p = path.resolve(process.cwd(), 'config/my-profile.yml');
if (!existsSync(p)) throw new Error(`Profile missing: ${p}`);
loadProfile(p);
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
import path from 'node:path';
const p = path.resolve(process.cwd(), profileArg);
if (!existsSync(p)) throw new Error(`Profile not found: ${p} (cwd=${process.cwd()})`);
loadProfile(p);

Type guard

function hasReadableFile(p) {
  try { return existsSync(p) && statSync(p).isFile(); } catch { return false; }
}

Try / catch

try {
  const profile = loadProfile(customPath);
} catch (e) {
  if (e.message.startsWith('Profile configuration file not found')) {
    console.error(`Fix --profile path: ${e.message}. Falling back to config/profile.yml.`);
    return loadProfile(null);
  }
  throw e;
}

Prevention

When it happens

Trigger: loadProfile('/path/to/my-profile.yml') where that file does not exist — e.g. a typo'd or relative path resolved from the wrong working directory, a profile file deleted/renamed after being referenced, or a script passing a path variable that was never populated.

Common situations: Running the ATS exporter from a different cwd so a relative path no longer resolves; pointing CAREER_OPS_PROFILE or an argument at a teammate's path; renamed profile during repo restructuring; CI checkout missing the gitignored personal profile.

Understand the failure class

Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.

Related errors


AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01). Data as JSON: /api/errors/ffd4b80537015409. Report an issue: GitHub.