santifer/career-ops · error · Error
Cannot read benchmarks at ${path}: ${err.message}
Error message
Cannot read benchmarks at ${path}: ${err.message} What it means
loadBenchmarks resolves the benchmarks file (--benchmarks path > config/benchmarks.yml > templates/benchmarks.yml) and calls yaml.load(readFileSync(path)). This error wraps any failure in that step: file not found, permission denied, or a YAML syntax error. The wrapped err.message distinguishes ENOENT from YAMLException.
Source
Thrown at funnel-velocity.mjs:228
median: days.length >= HOP_MIN_N ? median(days) : null,
p75: days.length >= HOP_MIN_N ? p75(days) : null,
insufficientData: days.length < HOP_MIN_N,
sameDayExcluded,
censored,
};
}
return result;
}
// --- Benchmarks ---
export function loadBenchmarks(explicitPath) {
const path = explicitPath
|| (existsSync(join(CAREER_OPS, 'config/benchmarks.yml')) ? join(CAREER_OPS, 'config/benchmarks.yml') : join(CAREER_OPS, 'templates/benchmarks.yml'));
let doc;
try {
doc = yaml.load(readFileSync(path, 'utf-8'));
} catch (err) {
throw new Error(`Cannot read benchmarks at ${path}: ${err.message}`);
}
if (!doc || typeof doc.benchmarks !== 'object' || doc.benchmarks === null) {
throw new Error(`Malformed benchmarks file at ${path}: expected a top-level "benchmarks" map`);
}
return { benchmarks: doc.benchmarks, path };
}
/** Classify an own-rate percentage against a benchmark's range (inclusive). */
export function classify(ownPct, metric) {
if (ownPct === null || ownPct === undefined || !metric || !Array.isArray(metric.range_pct)) return null;
const [lo, hi] = metric.range_pct;
const band = ownPct < lo ? 'below-range' : ownPct > hi ? 'above-range' : 'within-range';
const typical = metric.typical_pct;
return {
band,
ownPct,
rangePct: [lo, hi],
typicalPct: typical ?? null,View on GitHub (pinned to 9b17a8ac97)
Solutions
- Verify the file exists: ls templates/benchmarks.yml (or your custom path).
- Validate the YAML syntax: node -e "require('js-yaml').load(require('fs').readFileSync('templates/benchmarks.yml','utf-8'))".
- If using --benchmarks, confirm the path is correct and readable.
- Restore templates/benchmarks.yml from git if deleted: git checkout HEAD -- templates/benchmarks.yml.
Defensive patterns
Strategy: try-catch
Validate before calling
import { existsSync, readFileSync } from 'fs';
import * as yaml from 'js-yaml';
function validateBenchmarksFile(path) {
if (!existsSync(path)) throw new Error(`Benchmarks file not found: ${path}`);
let doc;
try {
doc = yaml.load(readFileSync(path, 'utf-8'));
} catch (err) {
throw new Error(`YAML syntax error in ${path}: ${err.message}`);
}
return doc;
} Try / catch
import { loadBenchmarks } from './funnel-velocity.mjs';
try {
const { benchmarks, path } = loadBenchmarks();
} catch (err) {
console.error(`Benchmark load failed: ${err.message}`);
// Restore from git or fix the file
process.exit(1);
} Prevention
- Keep templates/benchmarks.yml under version control and restore it if deleted.
- Validate custom config/benchmarks.yml with a YAML linter before committing.
- If using --benchmarks, verify the path resolves before running.
When it happens
Trigger: All three candidate paths are missing (deleted templates/benchmarks.yml); --benchmarks points to a non-existent file; the YAML has a syntax error (bad indentation, unclosed quote); permission denied on the file.
Common situations: User deletes templates/ without realizing benchmarks.yml lives there; a custom config/benchmarks.yml has invalid YAML; wrong CWD so the relative default path misses; a git operation removed the file.
Related errors
- Malformed benchmarks file at ${path}: expected a top-level "
- ROW_NOT_FOUND
- arbeitsagentur: entry "${entry.name || '(unnamed)'}" has no
- Malformed states file at ${statesPath}: expected a top-level
- Malformed states file at ${statesPath}: expected a top-level
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/a3bf66c34d7630f9.
Report an issue: GitHub.