📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 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 类型错误迁移:将 searchhttp input 的配置错误地简化为 simple,但没有调整对应的数据结构。
  • 配置管理工具处理不当:使用 Ansible、Terraform 等工具管理 Watch 配置时,YAML/JSON 模板对对象的序列化方式不正确,导致最终输出不是合法的对象结构。

3. 如何排查和解决这个异常 #

建议按以下顺序进行排查和修复:

  1. 获取完整的 Watch 定义:通过 GET _watcher/watch/<watch_id> 获取当前 Watch 的完整 JSON 定义,重点检查 input.simple 字段的实际值类型。
  2. 确认 payload 的数据结构:检查 simple 字段下是否是一个 JSON 对象({...}),而不是字符串、数字、布尔值或数组。
  3. 追溯配置来源:如果 Watch 是通过脚本或模板生成的,检查模板渲染前后的差异,确认对象是否正确生成。
  4. 验证修复后的配置:在测试环境或开发工具中验证修改后的 Watch 定义是否能被正确解析。

排查时需要注意的问题 #

  • 不要只看错误表面信息,需要结合完整的 Watch JSON 定义来判断 simple 字段的实际值类型。
  • 如果 Watch 是通过 Kibana 界面创建的,注意查看"高级设置"中的原始 JSON,确认 input 部分的结构是否完整。
  • 使用 _watcher/watch/<id>/_execute API 可以在不创建 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 字段下始终是一个 {...} 结构,或者根据实际需求切换到 searchhttp 等更合适的 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);
}