You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

js-yaml 3.10.0加载YAML 1.2锚点报错:无法合并映射

解决js-yaml 3.10.0加载YAML锚点数组时的合并错误

我刚好踩过这个坑,咱们一步步拆解问题、解决问题:

问题重现

先还原下你的场景,YAML文件写法大概是这样:

defaultEd: &defaultEd
  - "高中"
  - "本科"
user:
  name: "张三"
  education: <<: *defaultEd

对应的Node.js加载代码:

const yaml = require('js-yaml');
const fs = require('fs');

try {
  const doc = yaml.safeLoad(fs.readFileSync('someTest.yml', 'utf8'));
  console.log(doc);
} catch (e) {
  console.error(e.message);
}

报错详情

运行后会精准抛出这个错误:

cannot merge mappings; the provided source object is unacceptable

如果someTest.yml文件不存在,还会额外收到提示:

Error: ENOENT: no such file or directory, open 'someTest.yml'

原因分析

js-yaml 3.x版本里,<<这个合并操作符只支持处理映射(键值对结构),完全不兼容数组类型的锚点。当你用<<:*defaultEd去引用数组锚点时,库会强行把数组当作映射来解析合并,自然就触发了类型不匹配的错误。

解决方案

根据你想要education直接继承锚点数组内容的需求,最简单的修改就是去掉<<:,直接引用锚点:

修改后的YAML文件:

defaultEd: &defaultEd
  - "高中"
  - "本科"
user:
  name: "张三"
  education: *defaultEd

重新运行代码,就能得到你期望的输出:

{ user: { name: '张三', education: [ '高中', '本科' ] } }

如果之后需要在这个数组基础上追加元素,更稳妥的方式是直接扩展:

defaultEd: &defaultEd
  - "高中"
  - "本科"
user:
  name: "张三"
  education:
    - "高中"
    - "本科"
    - "硕士"

或者在Node.js代码里动态合并:

const doc = yaml.safeLoad(fs.readFileSync('someTest.yml', 'utf8'));
doc.user.education = [...doc.defaultEd, "硕士"];

关于文件不存在的处理

如果遇到“someTest.yml文件不存在”的提示,检查这两点:

  • 确认文件在当前Node.js进程的工作目录下(可以用console.log(process.cwd())查看当前路径)
  • 改用绝对路径读取文件更稳妥,比如:
const path = require('path');
const filePath = path.resolve(__dirname, 'someTest.yml'); // __dirname是当前脚本所在目录
const doc = yaml.safeLoad(fs.readFileSync(filePath, 'utf8'));

内容的提问来源于stack exchange,提问作者leeand00

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:19:17