在我们自托管的站点上,批准排队中的主题时因 HTTP 500 错误而失败,因为排队记录中包含 payload.tags = "macos"(一个字符串)。该格式错误的值此前已被 POST /posts 接口接受。
我理解客户端应该发送标签数组。我要报告的问题是:无效的标量值可以被接受进入审核队列,并且直到版主批准帖子时才在后续步骤中失败。
版本: 2026.10.0-latest,提交哈希 3f2bf92368c78a7fa9a755f3d046adf35dd4459b。
事故证据
由于 approve_post_count 设置,该帖子需要审批。
在 2026-10-22 13:37:52 UTC,原始的 Rails 请求参数中已经包含:
"tags" => "macos"
该请求为 POST /posts,对应的访问日志记录了 HTTP 200 状态码。提交的参数名称为 title、raw、category 和 tags。
读取待审核的可审核对象确认如下:
{
"type": "ReviewableQueuedPost",
"status": 0,
"version": 0,
"topic_id": null,
"payload": {
"tags": "macos"
}
}
这是相关字段的摘录,省略了标题、正文和用户信息。审核 UI 将该标签显示为五个单独的字母:m、a、c、o、s。
点击“批准”产生了以下异常(日志中有五组发生记录):
NoMethodError (undefined method '-' for an instance of String)
lib/discourse_tagging.rb:932:in 'DiscourseTagging.tags_for_saving'
lib/discourse_tagging.rb:43:in 'DiscourseTagging.tag_topic_by_names'
lib/discourse_tagging.rb:30:in 'DiscourseTagging.tag_topic'
lib/topic_creator.rb:228:in 'TopicCreator#setup_tags'
lib/topic_creator.rb:60:in 'TopicCreator#create'
lib/post_creator.rb:519:in 'PostCreator#create_topic'
lib/post_creator.rb:209:in 'block in PostCreator#create'
lib/post_creator.rb:419:in 'block in PostCreator#transaction'
lib/post_creator.rb:419:in 'PostCreator#transaction'
lib/post_creator.rb:207:in 'PostCreator#create'
app/models/reviewable_queued_post.rb:110:in 'ReviewableQueuedPost#perform_approve_post'
app/models/reviewable.rb:433:in 'Kernel#public_send'
app/models/reviewable.rb:433:in 'block in Reviewable#perform'
app/models/reviewable.rb:431:in 'Reviewable#perform'
app/controllers/reviewables_controller.rb:287:in 'ReviewablesController#perform'
相关代码
这些是在上述提交版本的运行容器中检查过的代码路径:
- PostsController#create_params 调用了
params.permit(tags: %i[id name]),但没有使用返回的过滤后的参数。随后它通过result[f] = params[f]分配原始值。 - NewPostManager#enqueue 直接将
@args[:tags]复制到可审核对象的 payload 中。 - ReviewableQueuedPost#create_options 仅在值已经是 Array 时才转换标签,保持标量字符串不变。
- DiscourseTagging.tags_for_saving 然后在批准用户可以创建标签的情况下评估
tags_arg - tag_names,这对字符串会引发异常。
预期行为
在创建可审核对象之前,拒绝标量 tags 参数并给出清晰的验证错误,或者如果这是预期的兼容性行为,则对其进行规范化。现有的格式错误的可审核对象也应该优雅地失败,而不是在审核过程中导致未处理的 500 错误。
临时解决方案及此报告的局限性
编辑可审核对象,删除旧标签,选择现有的 macos 标签并保存后,payload.tags 变为标签对象数组。回读确认版本为 1,状态仍为待处理,UI 再次显示一个标签。我在做出该更改后尚未重试批准操作。
原始提交者的客户端未知。本报告并未确立原生编辑器会生成标量标签这一事实。它是基于实际请求、存储的可审核对象、异常以及检查的代码;我未在干净的安装环境中单独复现此问题。
对于开发环境的复现,测试路径是:要求非工作人员用户的帖子需要审批,使用标量 tags: "macos" 和其他有效字段提交 POST /posts,然后以管理员身份批准生成的排队帖子。
有一个关于相同 String 减法异常的旧 API 讨论。本报告重点关注无效值被接受进入审核队列并在稍后破坏批准流程的问题。