{"record":{"id":"e161d2306deef653","repo":"santifer/career-ops","slug":"file-is-not-valid-yaml-string-err-message-split-0-refusing","errorCode":null,"errorMessage":"${file} is not valid YAML (${String(err.message).split('\n')[0]}) — refusing to overwrite it. Fix the file and re-run; nothing was changed.","messagePattern":"(.+?) is not valid YAML \\((.+?)\\) — refusing to overwrite it\\. Fix the file and re-run; nothing was changed\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins.mjs","lineNumber":243,"sourceCode":"  // Absent is not unreadable: no file means a first enable, which is the whole\n  // point of the function. Only an existing-but-unparseable file is a refusal.\n  if (raw == null) return {};\n  // An empty or comment-only file is \"no config yet\", not a corrupt one, and it\n  // must take the same path as an absent one. Decided from the text rather than\n  // from what the parser does with it: js-yaml 4 returns undefined for an empty\n  // document and js-yaml 5 throws \"expected a document, but the input is empty\",\n  // so inferring it from the parser would make this refuse to write over a\n  // comment-only config on one major and not the other.\n  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);","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/plugins.mjs#L225-L261","documentation":"parsePluginConfig loads config/plugins.yml before writing enable/disable flags into it. If the file has content but yaml.load fails, it throws rather than proceeding — the library refuses to overwrite a file it cannot parse, since doing so would silently destroy the user's config. Nothing is modified when this fires.","triggerScenarios":"Calling the plugin enable/disable write path (e.g. plugins.mjs set/enable/disable) while config/plugins.yml contains malformed YAML — bad indentation, tabs, unclosed quotes, stray characters.","commonSituations":"Hand-editing plugins.yml with a tab character; merging config changes that broke indentation; copy-pasting YAML from docs with smart quotes; a truncated write from a crashed editor.","solutions":["Open config/plugins.yml and fix the YAML syntax — the error includes the parser's first error line to locate it","Validate the file with a YAML linter or node -e \"require('yaml').load(require('fs').readFileSync('config/plugins.yml','utf8'))\"","Replace tabs with spaces; ensure consistent 2-space indentation and quoted strings where needed","Re-run the plugins command after the file parses cleanly"],"exampleFix":"// before (broken YAML: tab indentation)\nplugins:\n\tmy-plugin:\n\t\tenabled: true\n// Error: config/plugins.yml is not valid YAML (bad indentation of a mapping entry) ...\n// after\nplugins:\n  my-plugin:\n    enabled: true","handlingStrategy":"validation","validationCode":"import { parseDocument } from 'yaml';\nconst doc = parseDocument(readFileSync('config/plugins.yml', 'utf8'));\nif (doc.errors.length) throw new Error('plugins.yml has YAML errors: ' + doc.errors[0]);","typeGuard":"null","tryCatchPattern":"try { await pluginsCmd.enable('my-plugin'); } catch (e) { if (e.message.includes('is not valid YAML')) { console.error(e.message); /* surface parser line, do not auto-rewrite */ } throw e; }","preventionTips":["Edit YAML with an editor that shows syntax errors; never use tabs","Keep config/plugins.yml under version control so regressions are diffable","Run a YAML linter in CI over config files"],"tags":["yaml","config","plugins"],"backgroundTag":"yaml-parse-error","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"}