santifer/career-ops · error · Error
config/profile.yml not found: fill it in first
Error message
config/profile.yml not found: fill it in first
What it means
When no customProfilePath argument is given, loadProfile falls back to CAREER_OPS_PROFILE or config/profile.yml and requires that default file to exist. This is the deliberate 'fails closed' onboarding gate: the exporter refuses to run on an uninitialized checkout instead of producing an empty ATS export. The message tells the user exactly which file to create.
Source
Thrown at scripts/export-ats-text.mjs:234
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';
if (customCvPath) {
if (!existsSync(customCvPath)) {
throw new Error(`CV file not found at: ${customCvPath}`);
}View on GitHub (pinned to 1696bec4d0)
Solutions
- Create and fill in config/profile.yml (name, email, phone, location, links) at the repository root — this is the intended fix per the onboarding steps.
- If your profile lives elsewhere, either export CAREER_OPS_PROFILE=/abs/path/profile.yml or pass it as the first argument to loadProfile.
- Run the exporter from the repository root (or fix the cwd) so the relative default path resolves.
Example fix
// before $ node scripts/export-ats-text.mjs # config/profile.yml missing // after $ export CAREER_OPS_PROFILE=$HOME/.career-ops/profile.yml $ node scripts/export-ats-text.mjs
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'node:fs';
const source = process.env.CAREER_OPS_PROFILE || 'config/profile.yml';
if (!existsSync(source)) {
throw new Error(`Run first-run onboarding: create ${source} (see config/profile.example.yml)`);
}
loadProfile(); Try / catch
try {
const profile = loadProfile();
} catch (e) {
if (e.message.includes('config/profile.yml not found')) {
console.error('Setup incomplete: copy config/profile.example.yml to config/profile.yml and fill it in.');
process.exitCode = 1;
} else throw e;
} Prevention
- Complete first-run onboarding (create config/profile.yml from the example) before running ATS exports.
- Export CAREER_OPS_PROFILE in your shell profile or CI so the default path is explicit and absolute.
- In CI, add a step asserting existsSync('config/profile.yml') before any script that loads the profile.
When it happens
Trigger: Calling loadProfile() (or loadProfile(null, cvPath)) in a repo where config/profile.yml does not exist and CAREER_OPS_PROFILE is unset — e.g. a fresh clone before onboarding, or running from a cwd where the relative path doesn't resolve.
Common situations: Fresh clone of career-ops before the first-run setup; running the script from a subdirectory so 'config/profile.yml' resolves wrong; CAREER_OPS_PROFILE set to a path that doesn't exist (env override also checked via existsSync and hits this same message); CI checkout without the gitignored personal config.
Related errors
- APIFY_TOKEN not set — enable apify in config/plugins.yml and
- gmail: missing GMAIL_CLIENT_ID / GMAIL_CLIENT_SECRET / GMAIL
- H1B_API_BASE is set but empty. Unset it to use the default e
- H1B_API_BASE is not a valid URL: ${trimmed}
- H1B_API_BASE must not contain a query string or a fragment.
AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01).
Data as JSON: /api/errors/4411b8628b4bd079.
Report an issue: GitHub.