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

  1. Verify the file exists: ls templates/benchmarks.yml (or your custom path).
  2. Validate the YAML syntax: node -e "require('js-yaml').load(require('fs').readFileSync('templates/benchmarks.yml','utf-8'))".
  3. If using --benchmarks, confirm the path is correct and readable.
  4. 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

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


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/a3bf66c34d7630f9. Report an issue: GitHub.