适用版本: 6.8-8.x
1. 错误说明 #
报错 failed to parse [<type>] action [<watch_id>/<action_id>]. failed to parse [fields] field 表示 Elasticsearch 在解析某个 action 的 fields 配置时失败了。
从附录代码可以看到,解析器直接调用 parser.map() 读取 fields。这意味着 fields 必须是一个标准 JSON 对象。如果这里给了字符串、数组、格式损坏的对象,或者对象内部存在无法解析的结构,就会抛出该异常。
2. 常见触发场景 #
fields被写成字符串,例如把整段 JSON 当作文本传入。fields被写成数组,但解析逻辑期望的是键值对象。- 模板展开后生成了非法 JSON,导致
parser.map()失败。
错误示例:
{
"actions": {
"notify": {
"slack": {
"fields": "severity=high"
}
}
}
}
3. 排查方法 #
- 找出报错的具体 Watcher 和 action。
- 查看最终请求体中的
fields是否为 JSON 对象,而不是字符串或数组。 - 如果
fields来自模板生成,检查模板渲染结果是否仍然是合法对象。 - 将
fields单独抽出来做 JSON 校验,确认字段名和值都能被正常解析。
4. 修复方法 #
- 把
fields改成标准对象结构。 - 不要把对象序列化成字符串后再传给
fields。 - 对模板或程序化生成逻辑增加结构校验,确保输出始终是 map。
修正示例:
{
"actions": {
"notify": {
"slack": {
"fields": {
"severity": "high",
"service": "billing"
}
}
}
}
}
5. 预防建议 #
- 对
fields这类对象字段建立固定的数据结构定义。 - 在提交 Watcher 之前,对生成后的 JSON 做一次结构化校验。
- 如果接入层允许用户自定义字段,先做白名单和类型限制。
相关错误 #
附:日志上下文 #
proxy = HttpProxy.parse(parser);
} else if (Field.FIELDS.match(currentFieldName; parser.getDeprecationHandler())) {
try {
fields = parser.map();
} catch (Exception e) {
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. failed to parse [{}] field"; e; TYPE;
watchId; actionId; Field.FIELDS.getPreferredName());
}
} else {
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. unexpected token [{}/{}]"; TYPE; watchId;
actionId; token; currentFieldName);





