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

适用版本: 6.8-8.x

1. 错误异常的基本描述 #

could not parse [http] input for watch [id]. expected a string value in [field] array; but found [token] instead 表示 Watcher 正在解析 HTTP input 的数组字段,并要求数组成员都是字符串,但实际读到了对象、数字、布尔值或其他 token。

从源码来看,这类错误最常见于 extract 数组,因为 extract 用来声明要从响应中提取的字段路径,每一项都必须是字符串路径。

2. 为什么会发生这个错误 #

  • extract 中混入了对象、数组或数字。
  • 模板渲染后把字段路径列表渲染成了复合结构。
  • 把提取规则写成了对象数组,而当前版本只接受字符串数组。

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

  1. 检查报错中的数组字段名,通常会是 extract
  2. 逐项查看该数组的成员类型,确认每一项都是纯字符串。
  3. 如果需要更复杂的后处理,不要在 extract 里写对象,应改到 transform 或脚本中处理。

4. 如何解决这个错误 #

错误示例:

{
  "input": {
    "http": {
      "request": {
        "scheme": "https",
        "host": "example.org",
        "port": 443,
        "path": "/api/search"
      },
      "extract": [
        "hits.total",
        {
          "field": "hits.hits"
        }
      ]
    }
  }
}

修正示例:

{
  "input": {
    "http": {
      "request": {
        "scheme": "https",
        "host": "example.org",
        "port": 443,
        "path": "/api/search"
      },
      "extract": [
        "hits.total",
        "hits.hits"
      ]
    }
  }
}

5. 小结 #

expected a string value in [...] array 通常就是数组成员类型不对。把 extract 等数组统一改成字符串列表即可。

相关错误 #

附:日志上下文 #

extract = new HashSet<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
    if (token == XContentParser.Token.VALUE_STRING) {
        extract.add(parser.text());
    } else {
        throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. expected a string value in " +
            "[{}] array; but found [{}] instead", TYPE, watchId, currentFieldName, token);
    }
}
} else {
    throw new ElasticsearchParseException("could not parse [{}] input for watch [{}]. unexpected array field [{}]", TYPE,