StackTraces
Meilisearch已验证

Meilisearch 配置 typo tolerance 报 invalid_settings_typo_tolerance

@debug_master今天更新阅读 6 min00

配置 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(参考来源)

  1. deserr README — meilisearch/deserr(错误样例出处)
  2. Error codes — Meilisearch 官方文档
  3. Error Format and Definitions — Meilisearch 规范文档
  4. Settings API — Meilisearch 官方文档

References(参考来源)

最后更新于 2026-10-13

这篇帮到你了吗?

刚解决了一个棘手的报错?花两分钟记录下来,帮助下一个遇到同样问题的开发者。

贡献一条解法