YAML 缩进明明对齐了却报错?多半是 Tab 混进来了
Clash 配置提示缩进不一致、mapping items 未对齐,但肉眼看每一行都对得整整齐齐——这种情况几乎都是 Tab 和空格混用。本文说明 YAML 为什么禁止 Tab 缩进、怎么在编辑器里揪出它,以及另外两种视觉上看不出的缩进问题。
本文目录(6 节 · 约 2 分钟) +
- 01 为什么 YAML 不许用 Tab
- 02 怎么把 Tab 找出来
- 03 另外两种看不出来的缩进问题
- 04 为什么复制粘贴特别容易出问题
- 05 用工具直接定位
- 06 小结
一句话结论:YAML 规范明确禁止用 Tab 做缩进,而编辑器里 Tab 和空格长得一模一样。 如果报错说缩进有问题但你看着是对齐的,第一个要怀疑的就是这行的缩进里混了 Tab。
为什么 YAML 不许用 Tab
YAML 用缩进量表达层级关系,所以它必须能准确知道「这一行缩进了几格」。而 Tab 的显示宽度是由编辑器决定的——同一个 Tab 字符,在你的编辑器里显示成 4 格,在别人的编辑器里可能是 8 格或 2 格。如果允许 Tab 参与缩进,同一份文件在不同人手里就会解析出不同的结构。
所以 YAML 规范直接禁止了:缩进只能用空格。Tab 出现在缩进位置时,解析器会报错,常见措辞包括:
Tabs are not allowed as indentationAll mapping items must start at the same columnbad indentation of a mapping entry
第二种措辞最容易误导人——它说的是「同一层的几行没有从同一列开始」,你去看却发现明明对齐了。那是因为你看到的是渲染后的宽度,而解析器数的是字符个数。一行用了 1 个 Tab、另一行用了 4 个空格,视觉上都是 4 格宽,实际字符数一个是 1 一个是 4。
怎么把 Tab 找出来
在编辑器里打开「显示空白字符」
- VS Code:命令面板搜
View: Toggle Render Whitespace,或在设置里把editor.renderWhitespace设为all。Tab 会显示成箭头→,空格显示成小圆点。 - Sublime Text:
View → Show Whitespace。 - Notepad++:
视图 → 显示符号 → 显示空格与制表符。
打开之后问题一目了然:出错那行的缩进如果是箭头而不是圆点,就是它。
全局替换
VS Code 里可以直接执行 Convert Indentation to Spaces(命令面板搜 indentation),一次把整个文件的 Tab 缩进换成空格。顺便把 editor.insertSpaces 设为 true、editor.tabSize 设为 2,以后按 Tab 键就自动插入空格了。
最笨但最快的办法
把出错那一行的缩进整个删掉,然后手动按空格键重新缩进。改一行比配置整个编辑器快。
另外两种看不出来的缩进问题
一、同层缩进量不一致
proxies:
- name: 香港01
type: ss
server: hk1.example.com # ← 比上面多了一个空格
server 比 type 多缩进一格。有些编辑器在窄字体下几乎看不出一个空格的差异,但解析器很在意——它会认为 server 是 type 的子项,而 type 的值是个字符串不能有子项,于是报错。
统一用「两个空格一级」的习惯能避免绝大多数这类问题。
二、行尾有多余的空格
行尾空格通常不影响 YAML 解析,但在两种情况下会出事:一是节点名末尾带空格,导致策略组引用对不上(这个不报语法错,只报引用错);二是在使用块状标量(| 或 >)时,行尾空格会被当作内容的一部分。
很多编辑器可以设置保存时自动删除行尾空格,建议打开。
为什么复制粘贴特别容易出问题
从网页、聊天软件、PDF 里复制 YAML 片段时,缩进经常在中途被改写:
- 网页上的代码块可能本来就是用 Tab 缩进的
- 聊天软件会对连续空格做折叠或转义
- 有些论坛的富文本编辑器会把缩进转成不间断空格(
,U+00A0)——这个字符看起来就是空格,但它不是 ASCII 空格,YAML 不认
最后这种最阴险:显示空白字符也看不出区别,因为它渲染出来就是个空格。如果你确信缩进全是空格、也没有 Tab,却还是报错,试试把那几行删掉重打一遍。
用工具直接定位
把配置粘进配置校验器,它会指出出错的行号,并把解析器的英文报错翻成中文——包括专门识别「用了 Tab 缩进」这种情况并给出改法。比在编辑器里开着空白字符一行行扫要快。
工具在浏览器本地运行,配置不会上传。
小结
- 缩进报错但肉眼对齐 → 先怀疑 Tab
- 开「显示空白字符」,Tab 是箭头、空格是圆点
- 同层缩进差一个空格也会出错,统一用两格
- 从网页复制来的片段可能带不间断空格,看不出来,重打一遍最快
相关文章
Clash 报错「proxies 必须是数组」是什么意思,怎么改
Clash 或 mihomo 提示 proxies 不是数组、无法解析节点列表时,问题几乎都出在 YAML 的短横线和缩进上。本文说明这个报错的确切含义、四种常见成因,以及每种情况的正确写法。
「策略组引用了不存在的节点」——名字对不上的四种情况
Clash 启动失败提示策略组里的某个节点找不到,本质是 proxy-groups 里写的名字和 proxies 里的 name 没有完全一致。本文列出四种容易忽略的不一致来源,以及换订阅后批量失效的处理办法。
rules 最后为什么一定要写 MATCH,不写会怎样
MATCH 是 Clash 规则列表的兜底项,决定没有命中任何规则的流量走哪里。不写它不一定报错,但会导致「大部分网站正常、个别网站莫名其妙不走代理」这类难查的问题。本文说明它的作用、白名单与黑名单两种写法,以及规则顺序为什么重要。