{"record":{"id":"a3bf66c34d7630f9","repo":"santifer/career-ops","slug":"cannot-read-benchmarks-at-path-err-message","errorCode":null,"errorMessage":"Cannot read benchmarks at ${path}: ${err.message}","messagePattern":"Cannot read benchmarks at (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"funnel-velocity.mjs","lineNumber":256,"sourceCode":"      median: days.length >= HOP_MIN_N ? median(days) : null,\n      p75: days.length >= HOP_MIN_N ? p75(days) : null,\n      insufficientData: days.length < HOP_MIN_N,\n      sameDayExcluded,\n      censored,\n    };\n  }\n  return result;\n}\n\n// --- Benchmarks ---\nexport function loadBenchmarks(explicitPath) {\n  const path = explicitPath\n    || (existsSync(join(DATA_ROOT, 'config/benchmarks.yml')) ? join(DATA_ROOT, 'config/benchmarks.yml') : join(CODE_ROOT, 'templates/benchmarks.yml'));\n  let doc;\n  try {\n    doc = yaml.load(readFileSync(path, 'utf-8'));\n  } catch (err) {\n    throw new Error(`Cannot read benchmarks at ${path}: ${err.message}`);\n  }\n  if (!doc || typeof doc.benchmarks !== 'object' || doc.benchmarks === null) {\n    throw new Error(`Malformed benchmarks file at ${path}: expected a top-level \"benchmarks\" map`);\n  }\n  return { benchmarks: doc.benchmarks, path };\n}\n\n/** Classify an own-rate percentage against a benchmark's range (inclusive). */\nexport function classify(ownPct, metric) {\n  if (ownPct === null || ownPct === undefined || !metric || !Array.isArray(metric.range_pct)) return null;\n  const [lo, hi] = metric.range_pct;\n  const band = ownPct < lo ? 'below-range' : ownPct > hi ? 'above-range' : 'within-range';\n  const typical = metric.typical_pct;\n  return {\n    band,\n    ownPct,\n    rangePct: [lo, hi],\n    typicalPct: typical ?? null,","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/funnel-velocity.mjs#L238-L274","documentation":"funnel-velocity.mjs's loadBenchmarks reads the funnel benchmarks YAML (config/benchmarks.yml in DATA_ROOT, falling back to templates/benchmarks.yml in the code root). If readFileSync or yaml.load throws for any reason (missing file, bad permissions, invalid YAML syntax), it wraps the underlying error message and rethrows with the resolved path so you know exactly which file failed.","triggerScenarios":"Running funnel-velocity.mjs when neither config/benchmarks.yml nor templates/benchmarks.yml exists at the resolved locations; the file is unreadable due to permissions; or the file contains YAML syntax errors (tabs, bad indentation, unclosed quotes).","commonSituations":"A repo checkout missing templates/; DATA_ROOT pointed at a directory never initialized with a benchmarks.yml; a user hand-edited the YAML and broke its syntax; a wrong CAREER_OPS_DATA_DIR override resolving to an empty directory.","solutions":["Check the path printed in the error exists and is readable: `ls -l <path>`.","Restore the stock file: `git checkout -- templates/benchmarks.yml` or copy it from the repo template.","Validate the YAML syntax and fix indentation/tabs/unclosed quotes.","If relying on DATA_ROOT/config/benchmarks.yml, confirm the env override resolves where you expect."],"exampleFix":"// before (missing file)\nconst path = join(DATA_ROOT, 'config/benchmarks.yml'); // not present\n// after\ngit checkout -- templates/benchmarks.yml  // or copy templates/benchmarks.yml into DATA_ROOT/config/","handlingStrategy":"try-catch","validationCode":"import {existsSync, accessSync, constants} from 'fs';\nconst p = existsSync('config/benchmarks.yml') ? 'config/benchmarks.yml' : 'templates/benchmarks.yml';\ntry { accessSync(p, constants.R_OK); } catch { console.error(`benchmarks file missing/unreadable: ${p}`); process.exit(1); }","typeGuard":null,"tryCatchPattern":"try { const { benchmarks } = loadBenchmarks(); } catch (e) { if (/Cannot read benchmarks/.test(e.message)) { restoreFromTemplate(); } else throw e; }","preventionTips":["Keep templates/benchmarks.yml in the repo and never delete it.","Validate YAML before saving hand edits.","Check that CAREER_OPS_DATA_DIR / DATA_ROOT overrides point to an initialized directory.","Read the resolved path from the error message first — it names the exact failing file."],"tags":["yaml","file-io","config"],"backgroundTag":"file-read-failed","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}