适用版本: 6.8-8.x
1. 错误异常的基本描述 #
could not parse [simple] input for watch [<watch_id>]. expected an object but found [<token>] instead 是 Elasticsearch Watcher 在解析 Watch 定义时抛出的异常。该错误表明 Watcher 已识别出当前 input 类型为 simple,但 simple 字段下承载的 payload 值不符合预期的数据结构。
simple input 的设计用途是为 Watch 提供一段静态的键值对数据,作为后续 condition、transform 或 action 的执行上下文。因此其值必须是一个 JSON 对象(即 {...} 形式),而不能是字符串、数字、布尔值或数组等标量类型。
常见现象 #
- 创建或更新 Watch 时,Elasticsearch 返回
400 Bad Request,响应体中包含上述解析错误信息。 - Kibana 的 Watcher 管理界面无法正常保存 Watch 配置,前端提示请求失败。
- 已有的 Watch 在集群升级或配置迁移后变为红色(失败)状态。
- 在 Elasticsearch 日志中可以看到
ElasticsearchParseException相关的异常栈。
典型报错与异常栈 #
ElasticsearchParseException: could not parse [simple] input for watch [my_watch]. expected an object but found [VALUE_STRING] instead
at org.elasticsearch.xpack.watcher.input.simple.SimpleInput.parse(SimpleInput.java)
at org.elasticsearch.xpack.watcher.input.InputRegistry.parse(InputRegistry.java)
at org.elasticsearch.xpack.watcher.watch.WatchParser.parseWatch(WatchParser.java)
2. 为什么会发生这个错误 #
simple input 要求其值必须是一个 JSON 对象,这是因为 Watcher 内部将 simple 的 payload 作为 Payload.Simple 实例来处理,构造时直接调用 parser.map() 方法,该方法要求当前解析位置必须是一个对象的起始标记(START_OBJECT)。如果实际遇到的是字符串、数字或其他类型标记,解析器就会抛出上述异常。
常见原因通常包括:
- 直接赋值标量值:误以为
simple可以直接等于某个字符串或数字,例如"simple": "ok"或"simple": 123。 - 模板渲染结果不符合预期:使用 Mustache 模板或脚本动态生成 Watch 定义时,模板引擎将对象渲染成了纯文本字符串,导致最终 JSON 结构改变。
- JSON 结构书写错误:遗漏了外层花括号,或将数组当作对象使用,例如
"simple": ["key1", "value1"]。 - 从其他 input 类型错误迁移:将
search或httpinput 的配置错误地简化为simple,但没有调整对应的数据结构。 - 配置管理工具处理不当:使用 Ansible、Terraform 等工具管理 Watch 配置时,YAML/JSON 模板对对象的序列化方式不正确,导致最终输出不是合法的对象结构。
3. 如何排查和解决这个异常 #
建议按以下顺序进行排查和修复:
- 获取完整的 Watch 定义:通过
GET _watcher/watch/<watch_id>获取当前 Watch 的完整 JSON 定义,重点检查input.simple字段的实际值类型。 - 确认 payload 的数据结构:检查
simple字段下是否是一个 JSON 对象({...}),而不是字符串、数字、布尔值或数组。 - 追溯配置来源:如果 Watch 是通过脚本或模板生成的,检查模板渲染前后的差异,确认对象是否正确生成。
- 验证修复后的配置:在测试环境或开发工具中验证修改后的 Watch 定义是否能被正确解析。
排查时需要注意的问题 #
- 不要只看错误表面信息,需要结合完整的 Watch JSON 定义来判断
simple字段的实际值类型。 - 如果 Watch 是通过 Kibana 界面创建的,注意查看"高级设置"中的原始 JSON,确认
input部分的结构是否完整。 - 使用
_watcher/watch/<id>/_executeAPI 可以在不创建 Watch 的情况下测试 Watch 定义的合法性,这比直接创建更安全。
4. 如何解决这个错误 #
正确的 simple input 写法 #
simple input 的值必须是一个对象。以下是正确的写法示例:
{
"input": {
"simple": {
"status": "ok",
"threshold": 80,
"env": "production"
}
}
}
错误示例与修正对照 #
错误示例 1:值为字符串
{
"input": {
"simple": "ok"
}
}
修正后:
{
"input": {
"simple": {
"value": "ok"
}
}
}
错误示例 2:值为数字
{
"input": {
"simple": 100
}
}
修正后:
{
"input": {
"simple": {
"threshold": 100
}
}
}
错误示例 3:值为数组
{
"input": {
"simple": ["a", "b", "c"]
}
}
修正后:
{
"input": {
"simple": {
"items": ["a", "b", "c"]
}
}
}
如何选择正确的 input 类型 #
如果修复后发现 simple 并不适合你的使用场景,可以考虑切换到其他 input 类型:
| input 类型 | 适用场景 |
|---|---|
simple | 需要提供静态的键值对数据 |
search | 需要根据查询结果驱动 Watch 执行 |
http | 需要调用外部 HTTP 接口获取数据 |
chain | 需要按顺序执行多个 input |
借助 INFINI 产品提升排障效率 #
- INFINI Console 适合查看集群健康度、索引状态、错误趋势和请求画像,帮助快速判断 Watch 相关异常的影响范围。
- INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测、限流和流量治理,可以有效捕获 Watcher 执行过程中的异常请求,辅助定位配置问题。
5. 小结 #
could not parse [simple] input for watch ... expected an object but found ... instead 的根本原因是 simple input 的 payload 值不是 JSON 对象。只要确保 simple 字段下始终是一个 {...} 结构,或者根据实际需求切换到 search、http 等更合适的 input 类型,这个错误就能彻底消除。
建议在 Watch 配置管理中建立基本的 JSON 结构校验流程,避免将不符合对象结构的 payload 写入 simple input。
相关错误 #
附:日志上下文 #
下面保留当前页面中的源码片段,便于结合异常调用栈定位问题:
return payload.toXContent(builder, params);
}
public static SimpleInput parse(String watchId, XContentParser parser) throws IOException {
if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. expected an object but found [{}] instead",
TYPE, watchId, parser.currentToken());
}
Payload payload = new Payload.Simple(parser.map());
return new SimpleInput(payload);
}





