适用版本: 6.8-8.9
1. 错误异常的基本描述 #
invalid weekly day value. expected a string or a number value; but found [token] 是 Elasticsearch Watcher 模块在解析 weekly 类型定时触发器(schedule)时抛出的解析异常。该错误表示在 day 字段中传入的值既不是合法的字符串,也不是数字,而是一个不被接受的 JSON token 类型(如对象、数组、布尔值等)。
常见现象 #
- 创建或更新 Watcher 时返回
400 Bad Request,错误信息中包含上述异常描述。 - Kibana 或客户端调用
_watcher/watch/_execute或_watcher/watch/{id}/_update接口失败。 - Elasticsearch 日志中出现
ElasticsearchParseException堆栈,指向DayOfWeek.resolve解析逻辑。 - Watcher 定时任务无法按预期触发,导致告警、数据同步等自动化任务失效。
典型报错示例 #
{
"error": {
"root_cause": [
{
"type": "parse_exception",
"reason": "invalid weekly day value. expected a string or a number value; but found [START_OBJECT]"
}
],
"type": "parse_exception",
"reason": "invalid weekly day value. expected a string or a number value; but found [START_OBJECT]"
},
"status": 400
}
2. 为什么会发生这个错误 #
该错误的根本原因是 Watcher 的 weekly schedule 在解析 day 字段时,对值的类型有严格限制。Elasticsearch 源码中只允许以下两种类型:
- 字符串:如
"monday"、"tue"、"Wednesday"等完整的星期名称或缩写。 - 数字:如
1(星期一)到7(星期日)的整数。
当解析器遇到其他 JSON token 类型时,会直接抛出 ElasticsearchParseException,而不会尝试类型转换。常见触发场景包括:
- JSON 结构错误:将
day的值写成了对象或数组,例如{"day": "monday"}或["monday", "friday"]被错误地嵌套了一层。 - 模板渲染异常:使用 Mustache 模板或外部脚本生成 Watcher 配置时,变量替换后产生了非预期的数据结构,如布尔值
true或空对象{}。 - 客户端序列化问题:某些 Elasticsearch 客户端在序列化时,将星期值错误地包装成了对象(如 JSON 库将枚举类型序列化为
{"value": "MONDAY"})。 - 手动编辑失误:在手工编写 JSON 配置时,误加了花括号或方括号,导致值类型发生变化。
3. 如何排查和解决这个异常 #
建议按以下顺序进行排查:
- 获取完整报错信息:从接口返回或 Elasticsearch 日志中确认
token的具体类型(如START_OBJECT、START_ARRAY、VALUE_BOOLEAN等),这能直接指明问题方向。 - 检查 Watcher 配置的
trigger.schedule.weekly部分:重点查看day字段的结构和值类型。 - 如果是通过模板动态生成配置,检查模板渲染前后的差异,确认变量替换是否产生了非预期的 JSON 结构。
- 使用
_watcher/watch/{id}GET 接口 查看当前已保存的 Watcher 定义,与期望的配置进行对比。 - 在本地或测试环境复现:用最小化的 JSON 配置逐步验证,排除其他配置项的干扰。
排查时需要注意的问题 #
day字段可以是单个值,也可以是数组,但数组中的每个元素都必须是字符串或数字,不能是对象。- 星期字符串不区分大小写,但必须是 Elasticsearch 能识别的星期名称或缩写(如
mon、tue、wed、thu、fri、sat、sun)。 - 数字表示法中,
1代表星期一,7代表星期日,与java.time.DayOfWeek的规范一致。 - 如果该 Watcher 是通过 INFINI Console 或其他管理平台创建的,还需检查平台侧配置生成逻辑是否正确。
4. 如何解决这个错误 #
常用修复思路 #
修复前(错误示例) #
{
"trigger": {
"schedule": {
"weekly": {
"day": {"name": "monday"},
"at": ["09:00", "18:00"]
}
}
}
}
{
"trigger": {
"schedule": {
"weekly": {
"day": [{"value": "monday"}, {"value": "friday"}],
"at": "10:00"
}
}
}
}
修复后(正确示例) #
{
"trigger": {
"schedule": {
"weekly": {
"day": "monday",
"at": ["09:00", "18:00"]
}
}
}
}
{
"trigger": {
"schedule": {
"weekly": {
"day": ["monday", "friday"],
"at": "10:00"
}
}
}
}
{
"trigger": {
"schedule": {
"weekly": {
"day": [1, 5],
"at": ["09:00", "17:00"]
}
}
}
}
后续注意事项与推荐建议 #
- 在创建 Watcher 前,使用 JSON 校验工具验证配置的合法性,避免结构错误。
- 如果 Watcher 配置由代码或模板生成,在生成后、提交前增加一层结构校验,确保
day字段的类型符合预期。 - 对于复杂的定时需求,优先考虑使用
cron表达式替代weeklyschedule,灵活性和可读性都更好。 - 定期审查 Watcher 配置,尤其是在进行模板或客户端库升级后,防止序列化行为变化引入新问题。
借助 INFINI 产品提升排障效率 #
- INFINI Console 提供可视化的 Watcher 管理界面,支持配置校验和实时预览,避免手写 JSON 产生结构错误。
- INFINI Gateway 可以在请求到达 Elasticsearch 之前对 Watcher 相关 API 进行流量观测和异常请求拦截,帮助快速定位配置问题。
- 建议将 Watcher 的执行日志和错误事件统一接入监控面板,在定时任务未按预期触发时第一时间收到告警。
5. 小结 #
invalid weekly day value 错误的核心在于 day 字段的值类型不符合 Elasticsearch 的解析要求。修复时只需确保 day 的值是字符串或数字(或由其组成的数组),避免嵌套对象或数组结构。对于通过模板或代码生成配置的场景,建议在提交前增加类型校验,从源头防止此类问题发生。
相关错误 #
附:日志上下文 #
下面保留当前页面中的源码片段,便于结合异常调用栈定位问题:
if (token == XContentParser.Token.VALUE_STRING) {
return DayOfWeek.resolve(parser.text());
}
if (token == XContentParser.Token.VALUE_NUMBER) {
return DayOfWeek.resolve(parser.intValue());
}
throw new ElasticsearchParseException(
"invalid weekly day value. expected a string or a number value; but found [" + token + "]"
);





