{"record":{"id":"777e9a1ef01d619f","repo":"santifer/career-ops","slug":"file-does-not-contain-a-yaml-mapping-refusing-to-overwrite","errorCode":null,"errorMessage":"${file} does not contain a YAML mapping — refusing to overwrite it. Nothing was changed.","messagePattern":"(.+?) does not contain a YAML mapping — refusing to overwrite it\\. Nothing was changed\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins.mjs","lineNumber":252,"sourceCode":"  const hasContent = raw.split('\\n').some((line) => {\n    const t = line.trim();\n    return t !== '' && !t.startsWith('#');\n  });\n  if (!hasContent) return {};\n  let cfg;\n  try {\n    cfg = yaml.load(raw);\n  } catch (err) {\n    throw new Error(\n      `${file} is not valid YAML (${String(err.message).split('\\n')[0]}) — refusing to overwrite it. `\n      + 'Fix the file and re-run; nothing was changed.',\n    );\n  }\n  if (cfg == null) return {};   // empty file: same as absent\n  // A scalar or a list parses cleanly and is still not a config. Spreading one\n  // below would discard it just as silently as the empty object did.\n  if (typeof cfg !== 'object' || Array.isArray(cfg)) {\n    throw new Error(`${file} does not contain a YAML mapping — refusing to overwrite it. Nothing was changed.`);\n  }\n  return cfg;\n}\n\n// Write enabled:true/false into config/plugins.yml, merging (never clobbering\n// the user's other plugins or non-secret settings).\nfunction setEnabled(id, on, settings) {\n  const file = path.join(ROOT, 'config', 'plugins.yml');\n  const cfg = parsePluginConfig(existsSync(file) ? readFileSync(file, 'utf8') : null, file);\n  if (!cfg.plugins || typeof cfg.plugins !== 'object') cfg.plugins = {};\n  const prev = (cfg.plugins[id] && typeof cfg.plugins[id] === 'object') ? cfg.plugins[id] : {};\n  cfg.plugins[id] = { ...prev, ...(settings || {}), enabled: on };\n  mkdirSync(path.join(ROOT, 'config'), { recursive: true });\n  writeFileSync(file, '# career-ops plugin activation — see config/plugins.example.yml\\n' + yaml.dump(cfg), 'utf8');\n}\n\n// The capability card a user must consent to before a plugin runs.\nfunction capabilityCard(manifest, source) {","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/plugins.mjs#L234-L270","documentation":"parsePluginConfig requires the YAML file to parse to a mapping (object). A file containing a bare scalar (e.g. just 'true') or a list parses cleanly but is not a valid plugin config; spreading it would silently discard the user's data, so the library throws and changes nothing.","triggerScenarios":"Calling the plugin enable/disable path when config/plugins.yml contains a top-level YAML array or scalar instead of a key/value mapping.","commonSituations":"Rewriting plugins.yml as a simple list of names; a script that serialized an array into the file; pasting a list-format example from outdated docs.","solutions":["Convert the top-level structure to a mapping, e.g. plugins: { my-plugin: { enabled: true } }","Remove the stray scalar/list and rebuild the config from config/plugins.example.yml","Check git history (git diff config/plugins.yml) to find what replaced the mapping"],"exampleFix":"// before (a list, not a mapping)\n- my-plugin\n- other-plugin\n// Error: config/plugins.yml does not contain a YAML mapping ...\n// after\nplugins:\n  my-plugin:\n    enabled: true\n  other-plugin:\n    enabled: false","handlingStrategy":"validation","validationCode":"import { parse } from 'yaml';\nconst cfg = parse(readFileSync('config/plugins.yml', 'utf8'));\nif (cfg === null || typeof cfg !== 'object' || Array.isArray(cfg)) throw new Error('plugins.yml must be a YAML mapping at the top level');","typeGuard":"const isMapping = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);","tryCatchPattern":"try { await pluginsCmd.disable('my-plugin'); } catch (e) { if (e.message.includes('does not contain a YAML mapping')) { console.error(e.message); /* ask user to restructure or restore from example */ } throw e; }","preventionTips":["Only write mapping-shaped configs to plugins.yml","Restore from config/plugins.example.yml when restructuring","Review git diff before committing config rewrites"],"tags":["yaml","config","plugins"],"backgroundTag":"config-type-mismatch","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"}