{"record":{"id":"6daa02c6bf02da43","repo":"JuliusBrussee/caveman","slug":"hermes-plugins-enabled-uses-inline-yaml-refusing","errorCode":null,"errorMessage":"Hermes plugins.enabled uses inline YAML; refusing unsafe native merge","messagePattern":"Hermes plugins\\.enabled uses inline YAML; refusing unsafe native merge","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":7764,"sourceCode":"  if (new Set(routeIndexes.map((index) => lines[index]!.match(/^  ([^:]+):/)?.[1])).size !== routeIndexes.length) {\n    throw new Error(\"Hermes model provider/base_url keys are duplicated; refusing ambiguous install\");\n  }\n  const insertAt = routeIndexes[0] ?? model.start + 1;\n  for (const index of [...routeIndexes].sort((a, b) => b - a)) lines.splice(index, 1);\n  const routeBlock = [\n    `  ${HERMES_NATIVE_ROUTE_BEGIN}`,\n    '  provider: \"custom\"',\n    `  base_url: ${yamlQuote(appendUrlPath(gw, \"/w/hermes/v1\"))}`,\n    `  ${HERMES_NATIVE_ROUTE_END}`,\n  ];\n  lines.splice(insertAt, 0, ...routeBlock);\n\n  let pluginBlock: string | null = null;\n  const plugins = topLevelSection(lines, \"plugins\");\n  if (plugins) {\n    let enabled = -1;\n    for (let i = plugins.start + 1; i < plugins.end; i++) {\n      if (/^  enabled:\\s*\\[/.test(lines[i]!)) throw new Error(\"Hermes plugins.enabled uses inline YAML; refusing unsafe native merge\");\n      if (/^  enabled:\\s*(?:#.*)?$/.test(lines[i]!)) { enabled = i; break; }\n    }\n    if (enabled >= 0) {\n      if (!hermesNamedPluginEnabled(source, HERMES_NATIVE_PLUGIN_NAME)) {\n        const block = [`    ${HERMES_NATIVE_PLUGIN_BEGIN}`, `    - ${HERMES_NATIVE_PLUGIN_NAME}`, `    ${HERMES_NATIVE_PLUGIN_END}`];\n        lines.splice(enabled + 1, 0, ...block);\n        pluginBlock = block.join(\"\\n\");\n      }\n    } else {\n      const block = [`  ${HERMES_NATIVE_PLUGIN_BEGIN}`, \"  enabled:\", `    - ${HERMES_NATIVE_PLUGIN_NAME}`, `  ${HERMES_NATIVE_PLUGIN_END}`];\n      lines.splice(plugins.start + 1, 0, ...block);\n      pluginBlock = block.join(\"\\n\");\n    }\n  } else {\n    if (lines.length > 0 && lines[lines.length - 1]!.trim()) lines.push(\"\");\n    const block = [HERMES_NATIVE_PLUGIN_BEGIN, \"plugins:\", \"  enabled:\", `    - ${HERMES_NATIVE_PLUGIN_NAME}`, HERMES_NATIVE_PLUGIN_END];\n    lines.push(...block);\n    pluginBlock = block.join(\"\\n\");","sourceCodeStart":7746,"sourceCodeEnd":7782,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/index.ts#L7746-L7782","documentation":"This error is thrown by the Hermes native-integration writer when scanning the top-level `plugins:` section of the Hermes config YAML. It only recognizes a block-style `enabled:` list (a line like `enabled:` followed by list items), because that is the only format it can safely merge entries into. If `plugins.enabled` is written as an inline YAML flow sequence (`enabled: [a, b]`), a naive native merge could corrupt the user's config, so the tool refuses rather than guessing.","triggerScenarios":"Running a `caveman` command that installs/updates the Hermes native plugin when the Hermes config file contains `plugins:\\n  enabled: [...]` (inline array) instead of block-style list items.","commonSituations":"Users or other tools generate Hermes config with `yaml.dump(..., default_flow_style=...)` or JSON-style serialization producing inline arrays; hand-edited configs written in compact YAML style; configs migrated from other agents that use inline lists.","solutions":["Convert `plugins.enabled` in the Hermes config from inline YAML (`enabled: [\"x\", \"y\"]`) to block style (`enabled:\\n    - x\\n    - y`), then rerun the command.","Regenerate the Hermes config with a block-style YAML serializer (no flow style for sequences).","Remove the `enabled` key entirely and let the tool create the block-style list with its own begin/end markers.","Skip native Hermes installation and configure Hermes manually if you must keep the inline format."],"exampleFix":"# before\nplugins:\n  enabled: [my_plugin, other]\n# after\nplugins:\n  enabled:\n    - my_plugin\n    - other","handlingStrategy":"validation","validationCode":"const lines = cfg.split(\"\\n\");\nconst i = lines.findIndex(l => /^  enabled:\\s*\\[/.test(l));\nif (i !== -1) throw new Error(\"Rewrite plugins.enabled to block-style YAML before running caveman\");","typeGuard":"const isInlineEnabled = (yaml: string) => /^  enabled:\\s*\\[/.test(yaml);","tryCatchPattern":"try { await cavemanInstallHermes(); } catch (e) { if (String(e.message).includes(\"inline YAML\")) rewritePluginsEnabledToBlockStyle(cfgPath); }","preventionTips":["Always serialize Hermes config with block-style sequences (default_flow_style=false, flow_style=False).","Keep plugins.enabled as a block list; never hand-edit it into an inline array.","Run a YAML lint that flags flow sequences under plugins.enabled."],"tags":["yaml","configuration","hermes"],"backgroundTag":"unsupported-config-value","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}