Параметр Scalar tags, принятый в очередь на проверку, вызывает HTTP 500 при одобрении

При одобрении поставленного в очередь топика на нашем self-hosted сайте возникла ошибка HTTP 500, так как запись в очереди содержала payload.tags = "macos" (строку). Некорректное значение уже было принято запросом POST /posts.

Я понимаю, что клиенты должны отправлять массив тегов. Проблема, которую я описываю, заключается в том, что невалидное скалярное значение может быть принято в очередь на проверку и привести к сбою только позже, когда модератор одобряет публикацию.

Версия: 2026.10.0-latest, коммит 3f2bf92368c78a7fa9a755f3d046adf35dd4459b.

Данные инцидента

Публикации требовалось одобрение из-за настройки approve_post_count.

В 13:37:52 UTC 22.10.2026 исходные параметры запроса Rails уже содержали:

"tags" => "macos"

Запрос был POST /posts, и соответствующая строка журнала доступа зафиксировала HTTP 200. Отправленные имена параметров были title, raw, category и tags.

Чтение ожидающего проверки объекта подтвердило:

{
  "type": "ReviewableQueuedPost",
  "status": 0,
  "version": 0,
  "topic_id": null,
  "payload": {
    "tags": "macos"
  }
}

Это выдержка по релевантным полям, где опущены название, тело сообщения и информация о пользователе. В интерфейсе проверки тег отображался пятью отдельными буквами: 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 преобразует теги только в том случае, если значение уже является массивом, оставляя скалярную строку без изменений.
  • DiscourseTagging.tags_for_saving затем выполняет вычисление tags_arg - tag_names, если пользователь, одобряющий публикацию, может создавать теги, что приводит к исключению для строки.

Ожидаемое поведение

Отклонять скалярный параметр tags с четкой ошибкой валидации до создания объекта для проверки или нормализовать его, если это предусмотренное поведение совместимости. Существующий некорректный объект для проверки также должен обрабатываться корректно, а не вызывать необработанную ошибку 500 во время модерации.

Обходной путь и ограничения данного отчета

Редактирование объекта для проверки, удаление старого тега, выбор существующего тега macos и сохранение изменили payload.tags на массив объектов тегов. При повторном чтении была подтверждена версия 1, статус все еще «ожидает», и в интерфейсе снова отображался один тег. Я не пробовал повторно одобрить публикацию после этого изменения.

Клиент, которым пользовался первоначальный отправитель, неизвестен. Данный отчет не утверждает, что нативный редактор генерирует скалярные теги. Он основан на фактическом запросе, сохраненном объекте для проверки, исключении и просмотренном коде; я не воспроизводил это отдельно на чистой установке.

Для воспроизведения в среде разработки следует протестировать следующий сценарий: потребовать одобрения для публикации пользователя, не являющегося персоналом, отправить POST /posts со скалярным значением tags: "macos" и другими валидными полями, затем одобрить получившуюся публикацию в очереди от имени администратора.

Существует более старое обсуждение API с тем же исключением вычитания строк. Этот отчет сосредоточен на том, что невалидное значение принимается в очередь на проверку и ломает процесс одобрения позже.

честно говоря, не уверен, откуда это берётся, но вот исправление для его блокировки.