santifer/career-ops · warning
⚠️ Could not parse config/profile.yml
Error message
⚠️ Could not parse config/profile.yml: ${err.message} What it means
gemini-eval.mjs wraps its config/profile.yml load (yaml.load) in a try/catch; when parsing or reading the file throws — invalid YAML syntax, wrong top-level types, or an unreadable file — this warning reports err.message and the language/modes_dir resolution is skipped entirely, leaving PATHS.shared and PATHS.oferta pointed at the default modes/. The evaluation continues with defaults; the profile's language settings are ignored for this run.
Solutions
- Run a YAML linter on config/profile.yml (`npx yaml-lint config/profile.yml` or paste into a YAML validator) to find the exact syntax error named in err.message.
- Fix the reported line — most often replace tabs with spaces, quote values containing ':' or '#', and correct indentation to consistent 2-space steps.
- If the file is beyond repair, restore from config/profile.example.yml and re-apply your settings, keeping valid YAML.
- Re-run the evaluation and confirm the warning no longer appears and the intended modes_dir is picked up.
Example fix
# before (config/profile.yml — invalid YAML, tab indentation) language: output: de modes_dir: modes/de # after language: output: de modes_dir: modes/de
Defensive patterns
Strategy: try-catch
Validate before calling
import { readFileSync } from 'node:fs';
import { parse } from 'yaml';
try {
parse(readFileSync('config/profile.yml', 'utf8'));
console.log('config/profile.yml is valid YAML');
} catch (err) {
console.error(`config/profile.yml invalid: ${err.message}`);
process.exitCode = 1;
} Try / catch
try {
const profile = yaml.load(readFileSync('config/profile.yml', 'utf8'));
// proceed
} catch (err) {
console.warn(`Could not parse config/profile.yml: ${err.message}`);
// fall back to defaults, and surface the message to the user so the file gets fixed
} Prevention
- Lint config/profile.yml with a YAML validator after every manual edit (2-space indentation, no tabs, quote values containing ':' or '#').
- Restore from config/profile.example.yml after a corrupted edit and re-apply changes incrementally.
- Commit a known-good profile to git so bad edits can be reverted with `git diff config/profile.yml`.
- Watch for the 'Could not parse config/profile.yml' warning in output — it silently disables all language/market settings.
When it happens
Trigger: config/profile.yml contains malformed YAML (bad indentation, tabs, unquoted special characters like ':' or '#' in values, duplicate keys in strict mode) or cannot be read (missing read permission); also thrown if yaml.load returns unexpected types that break property access inside the guarded block.
Common situations: Hand-editing profile.yml and breaking indentation or leaving a value like `modes_dir: modes/de #comment` with an odd character; pasting YAML from a doc with tabs instead of spaces; a partially written file after an interrupted edit; Windows line-ending or BOM issues in the file.
Related errors
- ⚠️ modes_dir " " escapes project root; using default modes/
- arbeitsagentur: entry
- Cannot read benchmarks at
- config/profile.yml is empty or invalid YAML: fill it in…
- ⚠️ Failed to parse profile.yml
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/1ffd91505a25d43b.
Report an issue: GitHub.
Appendix: source
Thrown at gemini-eval.mjs:130
if (rel.startsWith('..') || isAbsolute(customModesDir)) {
console.warn(`⚠️ modes_dir "${customModesDir}" escapes project root; using default modes/`);
} else {
if (existsSync(dirPath)) {
const candidateFiles = ['oferta.md', 'angebot.md', 'offre.md', 'kyujin.md', 'is-ilani.md', 'naukri.md'];
const found = candidateFiles.find((file) => existsSync(join(dirPath, file)));
if (found) {
modesDir = customModesDir;
evalFilename = found;
} else {
console.warn(`⚠️ No matching evaluation file found in ${customModesDir}; using default modes/oferta.md`);
}
} else {
console.warn(`⚠️ modes_dir "${customModesDir}" not found; using default modes/`);
}
}
}
} catch (err) {
console.warn(`⚠️ Could not parse config/profile.yml: ${err.message}`);
}
}
PATHS.shared = join(CODE_ROOT, modesDir, '_shared.md');
PATHS.oferta = join(CODE_ROOT, modesDir, evalFilename);
// ---------------------------------------------------------------------------
// CLI argument parsing
// ---------------------------------------------------------------------------
const args = process.argv.slice(2);
if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
console.log(`
╔══════════════════════════════════════════════════════════════════╗
║ career-ops — Gemini Evaluator (free-tier) ║
╚══════════════════════════════════════════════════════════════════╝
Evaluate a job offer using Google Gemini instead of Claude.View on GitHub (pinned to aac998c7ed)