設定 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
