santifer/career-ops · error
Malformed benchmarks file at
Error message
Malformed benchmarks file at ${path}: expected a top-level "benchmarks" map What it means
loadBenchmarks successfully parsed the YAML but the resulting document does not contain a non-null top-level `benchmarks` map. The function requires doc.benchmarks to be an object; an empty file, a bare scalar, an array, or a document keyed differently all fail this structural check and throw with the file path.
Solutions
- Open the file at the printed path and add/restore a top-level `benchmarks:` map.
- Restore the canonical shape from templates/benchmarks.yml in the repo.
- If the file was meant as config for another tool, move it; benchmarks.yml must key everything under `benchmarks:`.
Example fix
# before (malformed) funnel: applied_to_own: [10, 25] # after benchmarks: applied_to_own: [10, 25]
Defensive patterns
Strategy: validation
Validate before calling
import {readFileSync} from 'fs'; import yaml from 'js-yaml';
const doc = yaml.load(readFileSync('templates/benchmarks.yml','utf8'));
if (!doc || typeof doc.benchmarks !== 'object' || doc.benchmarks === null) throw new Error('benchmarks.yml must have a top-level "benchmarks" map'); Type guard
const hasBenchmarks = (d) => !!d && typeof d === 'object' && !Array.isArray(d) && typeof d.benchmarks === 'object' && d.benchmarks !== null;
Try / catch
try { loadBenchmarks(); } catch (e) { if (/Malformed benchmarks/.test(e.message)) { restoreTemplateAndRetry(); } else throw e; } Prevention
- Always keep `benchmarks:` as the single top-level key.
- Never leave the file empty or comment-only.
- Copy from templates/benchmarks.yml when editing rather than writing from memory.
When it happens
Trigger: benchmarks.yml exists but is empty; parses to null/a string/a list; or uses a top-level key other than `benchmarks` (e.g. `funnel:` or content nested under a comment header).
Common situations: A user rewrote the file from scratch guessing the format; a truncated or templated file with only comments; copying an unrelated YAML into config/benchmarks.yml.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Malformed states file at
- apify: entry has invalid field_map. Each of title, url…
- arbeitsagentur: entry
- Cannot read benchmarks at
- config/profile.yml is empty or invalid YAML: fill it in…
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/30ec0427f5b3a927.
Report an issue: GitHub.
Appendix: source
Thrown at funnel-velocity.mjs:259
sameDayExcluded,
censored,
};
}
return result;
}
// --- Benchmarks ---
export function loadBenchmarks(explicitPath) {
const path = explicitPath
|| (existsSync(join(DATA_ROOT, 'config/benchmarks.yml')) ? join(DATA_ROOT, 'config/benchmarks.yml') : join(CODE_ROOT, '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,
vsTypical: typical ? Math.round((ownPct / typical) * 10) / 10 : null,
source: metric.source ?? null,
year: metric.year ?? null,View on GitHub (pinned to aac998c7ed)