配置 typo tolerance 报 invalid_settings_typo_tolerance:字段值超出 u8 范围,且 twoTypos 必须大于 oneTypo
给索引的
typoTolerance设置传了非法值,PATCH /indexes/{uid}/settings/typo-tolerance直接返回 400。minWordSizeForTypos的oneTypo/twoTypos是 u8 类型,只能取 0–255,且twoTypos必须大于oneTypo。这类配置错误在请求阶段同步报错,不会生成taskUid——和大多数设置更新返回 202 + task 的流程不一样。适用 Meilisearch 全版本。
Issue & Env(案发现场与环境)
- 业务场景:想调宽松拼写容错,把
minWordSizeForTypos.oneTypo设成 1000(以为越大越宽松),结果PATCH /indexes/books_typo/settings/typo-tolerance直接返回 400,没有taskUid。 - 环境:Meilisearch v1.54.3,curl / JS SDK / Python SDK 均可复现。
- 关键区分:这是同步 400——请求体在服务端反序列化阶段就被拒了,根本没有进入任务队列。而正常的设置更新(即使值合法但格式不对类型)会返回 202 +
taskUid。看到返回体里带code字段而不是taskUid字段,就说明是同步校验失败。
StackTrace(堆栈日志)
请求体:
{
"typoTolerance": {
"minWordSizeForTypos": {
"oneTypo": 1000,
"twoTypos": 80
},
"enabled": true
}
}
返回 400:
{
"message": "Invalid value at `.typoTolerance.minWordSizeForTypos.oneTypo`: value: `1000` is too large to be deserialized, maximum value authorized is `255`",
"code": "invalid_settings_typo_tolerance",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid-settings-typo-tolerance"
}
这个错误样例来自 Meilisearch 维护的 deserr 库 README(deserr 是 Meilisearch 用来做请求体反序列化的库),原文逐字一致。官方错误码文档对该错误码的触发条件说明:enabled 字段必须为布尔值或 null;disableOnAttributes、disableOnWords 必须为字符串数组或 null;minWordSizeForTypos 的取值非法(超范围或 oneTypo/twoTypos 关系不满足)等。
Reproduce(复现代码)
curl -X PATCH 'http://localhost:7700/indexes/books_typo/settings/typo-tolerance' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer aSampleMasterKey' \
--data-binary '{"minWordSizeForTypos":{"oneTypo":1000,"twoTypos":80}}'
# 返回 400:
# {"message":"Invalid value at `.typoTolerance.minWordSizeForTypos.oneTypo`: value: `1000` is too large to be deserialized, maximum value authorized is `255`","code":"invalid_settings_typo_tolerance","type":"invalid_request","link":"https://docs.meilisearch.com/errors#invalid-settings-typo-tolerance"}
把 oneTypo 换回合法值(如 5)再发一次,才返回 202 + taskUid:
curl -X PATCH 'http://localhost:7700/indexes/books_typo/settings/typo-tolerance' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer aSampleMasterKey' \
--data-binary '{"minWordSizeForTypos":{"oneTypo":5,"twoTypos":9}}'
# 返回:{"taskUid": 51, "indexUid": "books_typo", "status": "enqueued", "type": "settingsUpdate", ...}
Root Cause(根因分析)
oneTypo / twoTypos 是 u8,合法区间只有 0–255
minWordSizeForTypos 的 oneTypo 和 twoTypos 在 Meilisearch 内部以 u8(无符号 8 位整数)存储,超过 255 的值在反序列化阶段就溢出。deserr 的反序列化错误把出错字段定位到 .typoTolerance.minWordSizeForTypos.oneTypo,并直接给出合法上限 255。用 serde 时同样的情况只会返回泛化的 bad_request,靠 deserr 才有这种字段级、可读的错误信息。
twoTypos 必须大于 oneTypo
minWordSizeForTypos 还有一个跨字段约束:twoTypos 的值必须大于 oneTypo(两个阈值分别表示「从多少字符起允许 1 个错字」「从多少字符起允许 2 个错字」,默认是 5 和 9)。比如 oneTypo: 6, twoTypos: 5 会触发同样的 invalid_settings_typo_tolerance。这是 deserr README 明确写出的校验规则,源码在 settings 校验逻辑里实现。
同步报错,不走任务队列
设置更新的正常流程是「返回 202 + taskUid,轮询任务到 succeeded」。但请求体的反序列化与字段校验发生在入队之前,校验失败直接同步返回 400。所以看到 400 + code,先别轮询任何 task——压根没有 task。
The Fix(解决方案)
第一步:把值改回合法区间
oneTypo、twoTypos都必须在 0–255 之间;twoTypos必须大于oneTypo;- 参考默认值:
oneTypo: 5、twoTypos: 9(即 1–4 字符 0 错字、5–8 字符 1 错字、≥9 字符 2 错字)。
第二步:检查同对象里其他字段的类型
按官方错误码文档,enabled 必须是布尔或 null,disableOnAttributes / disableOnWords 必须是字符串数组或 null。这些字段类型不对也会报同一个错误码。
第三步:修正后重发,等任务 succeeded 再验证
# 1. 修正后重发(返回 202 + taskUid)
curl -X PATCH 'http://localhost:7700/indexes/books_typo/settings/typo-tolerance' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer aSampleMasterKey' \
--data-binary '{"minWordSizeForTypos":{"oneTypo":8,"twoTypos":10}}'
# 2. 轮询任务直到 succeeded
curl 'http://localhost:7700/tasks/51' \
-H 'Authorization: Bearer aSampleMasterKey'
注意事项
- v1.45 起 typo tolerance 设置改动不再触发全量重索引,改完等任务
succeeded就能搜,代价比旧版本小得多(旧版本行为见 Meilisearch 改设置后全文索引不生效或需全量重建)。 - 想验证容错阈值有没有生效,用「5 字符错 1 个字母」和「4 字符错 1 个字母」两组查询对照,前者命中、后者不命中,即证明阈值按预期工作。
- 拼写容错是排序规则而不是过滤器,调大阈值只会让错拼结果更靠前,不会把精确匹配挤掉。
References(参考来源)
- deserr README — meilisearch/deserr(错误样例出处)
- Error codes — Meilisearch 官方文档
- Error Format and Definitions — Meilisearch 规范文档
- Settings API — Meilisearch 官方文档
References(参考来源)
- deserr README — meilisearch/deserr(错误样例来源)crates-io
- Error codes — Meilisearch 官方文档meilisearch-docs
- Error Format and Definitions — Meilisearch 规范文档meilisearch-spec
- Settings API — Meilisearch 官方文档meilisearch-docs
