قبول معلم Scalar tags في طابور المراجعة يسبب خطأ HTTP 500 عند الاعتماد

فشل اعتماد موضوع في قائمة الانتظار على موقعنا المستضاف ذاتيًا بسبب خطأ 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"
  }
}

هذا مقتطف للحقول ذات الصلة، مع حذف العنوان والمحتوى ومعلومات المستخدم. عرضت واجهة المراجعة الوسم كخمس حروف منفصلة: 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] مباشرةً إلى حمولة القابل للمراجعة.
  • يحوّل ReviewableQueuedPost#create_options الوسوم فقط عندما تكون القيمة مصفوفة بالفعل، مما يترك النص القياسي دون تغيير.
  • ثم يُقيّم DiscourseTagging.tags_for_saving التعبير tags_arg - tag_names عندما يكون بإمكان المستخدم المعتمد إنشاء وسوم، مما يؤدي إلى حدوث استثناء للنص.

السلوك المتوقع

رفض معامل tags القياسي مع خطأ تحقق واضح قبل إنشاء القابل للمراجعة، أو تطبيعه إذا كان ذلك سلوك التوافق المقصود. يجب أيضًا أن يفشل القابل للمراجعة غير الصالح الموجود مسبقًا بسلاسة بدلاً من التسبب في خطأ 500 غير مُعالج أثناء الإشراف.

حل بديل وحدود هذا التقرير

تعديل القابل للمراجعة، وإزالة الوسم القديم، واختيار الوسم macos الموجود مسبقًا، والحفظ غيّر payload.tags إلى مصفوفة من كائنات الوسوم. أكد القراءة الرجعية الإصدار 1، ما زال معلّقًا، وعرضت الواجهة الوسم واحدًا مرة أخرى. لم أجرب الاعتماد مرة أخرى بعد هذا التغيير.

عميل المرسل الأصلي مجهول. هذا التقرير لا يثبت أن محرر النظام الأساسي يولد وسومًا قياسية. إنه مبني على الطلب الفعلي، والقابل للمراجعة المخزن، والاستثناء، والكود المفحص؛ لم أقم بإعادته بشكل منفصل على تثبيت نظيف.

لإعادة إنتاج التطوير، المسار الذي يجب اختباره هو: تتطلب اعتماد منشور مستخدم غير موظف، أرسل POST /posts مع قياسي tags: "macos" وحقول صالحة أخرى، ثم اعتمد الموضوع المعلّق الناتج كمدير.

يوجد نقاش API أقدم يحتوي على نفس استثناء طرح النص. يركز هذا التقرير على قبول القيمة غير الصالحة في قائمة مراجعة الاعتماد وكسر الاعتماد لاحقًا.

بصراحة، لست متأكدًا من مصدر هذه المشكلة، لكن إليك إصلاحًا لحظرها.

إعجاب واحد (1)