تعطّل Git وصفحة خطأ Oops لحسابات المدير والمراقبين

ActionView::Template::Error (no implicit conversion of Array into String)

أعدتُ إنشاء خطأ صفحة العطل (Oops Page) الذي يبدو أنه يؤثر فقط على المسؤولين (admins) وفي بعض الحالات على حسابات الموظفين الآخرين، لكن في هذه الحالة على حساب المسؤول، وتحديداً على حسابات المسؤولين التي سبقت “مشكلة تعليق git” بمجرد محاولة تسجيل الدخول مرة أخرى.

ثم قمت بفحص السجلات (logs) الآن، بعد أن أصبحت أكثر إلماماً بكيفية عمل ميزة إخراج /logs، وهي رائعة!

يظهر هذا الخطأ كـ “خطأ فادح” (fatal error) وبدأ في اليوم 22، ويبدو شبيهاً جداً بمشكلة “تعليق git”، لكن في هذه الحالة يبقى دون حل على الرغم من عمليات إعادة البناء (rebuilds) المتعددة حتى هذه النقطة، مما يعني أن بعض حسابات المسؤولين معزولة فعلياً (locked out)، يرجى الرجوع إلى معلومات وسجلات التتبع (backtrace) أدناه:

المعلومات

Message

ActionView::Template::Error (no implicit conversion of Array into String)
app/serializers/current_user_serializer.rb:216:in 'CurrentUserSerializer#has_new_upcoming_changes'
lib/application_layout_preloader.rb:81:in 'ApplicationLayoutPreloader#preload_current_user_data'
lib/application_layout_preloader.rb:32:in 'ApplicationLayoutPreloader#preloaded_data'
app/helpers/application_helper.rb:987:in 'ApplicationHelper#preloaded_json'
app/views/layouts/application.html.erb:111
lib/topic_list_responder.rb:16:in 'block (2 levels) in TopicListResponder#respond_with_list'
lib/topic_list_responder.rb:7:in 'TopicListResponder#respond_with_list'
app/controllers/list_controller.rb:119:in 'block (2 levels) in class:ListController'
app/controllers/application_controller.rb:458:in 'block in ApplicationController#with_resolved_locale'
app/controllers/application_controller.rb:458:in 'ApplicationController#with_resolved_locale'
app/controllers/application_controller.rb:1140:in 'ApplicationController#ensure_dont_cache_page'
lib/middleware/omniauth_bypass_middleware.rb:35:in 'Middleware::OmniauthBypassMiddleware#call'
lib/middleware/crawler_hooks.rb:13:in 'Middleware::CrawlerHooks#call'
lib/content_security_policy/middleware.rb:12:in 'ContentSecurityPolicy::Middleware#call'
lib/middleware/anonymous_cache.rb:431:in 'Middleware::AnonymousCache#call'
lib/middleware/csp_script_nonce_injector.rb:13:in 'Middleware::CspScriptNonceInjector#call'
lib/middleware/track_view_session_id_injector.rb:12:in 'Middleware::TrackViewSessionIdInjector#call'
config/initializers/008-rack-cors.rb:14:in 'Discourse::Cors#call'
lib/middleware/default_headers.rb:13:in 'Middleware::DefaultHeaders#call'
config/initializers/100-quiet_logger.rb:20:in 'DiscourseRackQuietAssetsLogger#call'
config/initializers/100-silence_logger.rb:29:in 'SilenceLogger#call'
lib/middleware/enforce_hostname.rb:23:in 'Middleware::EnforceHostname#call'
lib/middleware/request_tracker.rb:384:in 'Middleware::RequestTracker#call'
lib/middlewar...

تتبع المسار (Backtrace):


Backtrace

activesupport (8.1.4) lib/active_support/values/time_zone.rb:461:in 'Date._parse'
activesupport (8.1.4) lib/active_support/values/time_zone.rb:461:in 'ActiveSupport::TimeZone#parse'
app/serializers/current_user_serializer.rb:216:in 'CurrentUserSerializer#has_new_upcoming_changes'
(eval at active_model_serializers-0.8.4/lib/active_model/serializer.rb:467):81:in 'CurrentUserSerializer#_fast_attributes'
active_model_serializers (0.8.4) lib/active_model/serializer.rb:456:in 'ActiveModel::Serializer#attributes'
active_model_serializers (0.8.4) lib/active_model/serializer.rb:480:in 'ActiveModel::Serializer#_serializable_hash'
active_model_serializers (0.8.4) lib/active_model/serializer.rb:359:in 'ActiveModel::Serializer#serializable_hash'
active_model_serializers (0.8.4) lib/active_model/serializer.rb:347:in 'ActiveModel::Serializer#as_json'
activesupport (8.1.4) lib/active_support/json/encoding.rb:53:in 'Oj::Rails::Encoder#encode'
activesupport (8.1.4) lib/active_support/json/encoding.rb:53:in 'ActiveSupport::JSON.encode'
activesupport (8.1.4) lib/active_support/core_ext/object/json.rb:42:in 'ActiveSupport::ToJsonWithActiveSupportEncoder#to_json'
active_model_serializers (0.8.4) lib/active_model/serializer.rb:331:in 'ActiveModel::Serializer#to_json'
multi_json (1.21.1) lib/multi_json/adapters/oj.rb:67:in 'Oj.dump'
multi_json (1.21.1) lib/multi_json/adapters/oj.rb:67:in 'MultiJSON::Adapters::Oj#dump'
multi_json (1.21.1) lib/multi_json/adapter.rb:110:in 'MultiJSON::Adapter.dump'
multi_json (1.21.1) lib/multi_json.rb:215:in 'MultiJSON.generate'
multi_json (1.21.1) lib/multi_json/deprecated.rb:34:in 'Kernel#public_send'
multi_json (1.21.1) lib/multi_json/deprecated.rb:34:in 'block in MultiJSON.deprecate_alias'
multi_json (1.21.1) lib/multi_json.rb:298:in 'Kernel#public_send'
multi_json (1.21.1) lib/multi_json.rb:298:in 'block (2 levels) in module:MultiJson'
lib/application_layout_preloader.rb:81:in 'ApplicationLayoutPreloader#preload_current_user_data'
lib/application_layout_preloader.rb:32:in 'ApplicationLayoutPreloader#preloaded_data'
app/helpers/application_helper.rb:987:in 'ApplicationHelper#preloaded_json'
app/views/layouts/application.html.erb:111
actionview (8.1.4) lib/action_view/base.rb:281:in 'Kernel#public_send'
actionview (8.1.4) lib/action_view/base.rb:281:in 'ActionView::Base#_run'
actionview (8.1.4) lib/action_view/template.rb:284:in 'block in ActionView::Template#render'
activesupport (8.1.4) lib/active_support/notifications.rb:212:in 'ActiveSupport::Notifications.instrument'
actionview (8.1.4) lib/action_view/template.rb:590:in 'ActionView::Template#instrument_render_template'
actionview (8.1.4) lib/action_view/template.rb:272:in 'ActionView::Template#render'
rack-mini-profiler (5.0.0) lib/mini_profiler/profiling_methods.rb:90:in 'block in ActionView::Template#profile_method'
actionview (8.1.4) lib/action_view/renderer/template_renderer.rb:77:in 'block in ActionView::TemplateRenderer#render_with_layout'
activesupport (8.1.4) lib/active_support/notifications.rb:210:in 'block in ActiveSupport::Notifications.instrument'
activesupport (8.1.4) lib/active_support/notifications/instrumenter.rb:58:in 'ActiveSupport::Notifications::Instrumenter#instrument'
activesupport (8.1.4) lib/active_support/notifications.rb:210:in 'ActiveSupport::Notifications.instrument'
actionview (8.1.4) lib/action_view/renderer/template_renderer.rb:75:in 'ActionView::TemplateRenderer#render_with_layout'
actionview (8.1.4) lib/action_view/renderer/template_renderer.rb:59:in 'ActionView::TemplateRenderer#render_template'
actionview (8.1.4) lib/action_view/renderer/template_renderer.rb:11:in 'ActionView::TemplateRenderer#render'
actionview (8.1.4) lib/action_view/renderer/renderer.rb:58:in 'ActionView::Renderer#render_template_to_object'
actionview (8.1.4) lib/action_view/renderer/renderer.rb:31:in 'ActionView::Renderer#render_to_object'
actionview (8.1.4) lib/action_view/rendering.rb:136:in 'block in ActionView::Rendering#_render_template'
actionview (8.1.4) lib/action_view/base.rb:308:in 'ActionView::Base#in_rendering_context'
actionview (8.1.4) lib/action_view/rendering.rb:135:in 'ActionView::Rendering#_render_template'
actionpack (8.1.4) lib/action_controller/metal/streaming.rb:179:in 'ActionController::Streaming#_render_template'
actionview (8.1.4) lib/action_view/rendering.rb:122:in 'ActionView::Rendering#render_to_body'
actionpack (8.1.4) lib/action_controller/metal/rendering.rb:192:in 'ActionController::Rendering#render_to_body'
actionpack (8.1.4) lib/action_controller/metal/renderers.rb:155:in 'ActionController::Renderers#render_to_body'
actionpack (8.1.4) lib/abstract_controller/rendering.rb:28:in 'AbstractController::Rendering#render'
actionpack (8.1.4) lib/action_controller/metal/rendering.rb:173:in 'ActionController::Rendering#render'
actionpack (8.1.4) lib/action_controller/metal/instrumentation.rb:31:in 'block (2 levels) in ActionController::Instrumentation#render'
activesupport (8.1.4) lib/active_support/benchmark.rb:17:in 'ActiveSupport::Benchmark.realtime'
actionpack (8.1.4) lib/action_controller/metal/instrumentation.rb:31:in 'block in ActionController::Instrumentation#render'
actionpack (8.1.4) lib/action_controller/metal/instrumentation.rb:100:in 'ActionController::Instrumentation#cleanup_view_runtime'
activerecord (8.1.4) lib/active_record/railties/controller_runtime.rb:48:in 'ActiveRecord::Railties::ControllerRuntime#cleanup_view_runtime'
actionpack (8.1.4) lib/action_controller/metal/instrumentation.rb:30:in 'ActionController::Instrumentation#render'
lib/topic_list_responder.rb:16:in 'block (2 levels) in TopicListResponder#respond_with_list'
actionpack (8.1.4) lib/action_controller/metal/mime_responds.rb:224:in 'ActionController::MimeResponds#respond_to'
lib/topic_list_responder.rb:7:in 'TopicListResponder#respond_with_list'
app/controllers/list_controller.rb:119:in 'block (2 levels) in class:ListController'
actionpack (8.1.4) lib/action_controller/metal/basic_implicit_render.rb:8:in 'ActionController::BasicImplicitRender#send_action'
actionpack (8.1.4) lib/abstract_controller/base.rb:221:in 'AbstractController::Base#process_action'
actionpack (8.1.4) lib/action_controller/metal/rendering.rb:199:in 'ActionController::Rendering#process_action'
actionpack (8.1.4) lib/abstract_controller/callbacks.rb:267:in 'block in AbstractController::Callbacks#process_action'
activesupport (8.1.4) lib/active_support/callbacks.rb:121:in 'block in ActiveSupport::Callbacks#run_callbacks'
app/controllers/application_controller.rb:458:in 'block in ApplicationController#with_resolved_locale'
i18n (1.14.8) lib/i18n.rb:354:in 'I18n::Base#with_locale'
app/controllers/application_controller.rb:458:in 'ApplicationController#with_resolved_locale'
activesupport (8.1.4) lib/active_support/callbacks.rb:130:in 'block in ActiveSupport::Callbacks#run_callbacks'
app/controllers/application_controller.rb:1140:in 'ApplicationController#ensure_dont_cache_page'
activesupport (8.1.4) lib/active_support/callbacks.rb:130:in 'block in ActiveSupport::Callbacks#run_callbacks'
activesupport (8.1.4) lib/active_support/callbacks.rb:141:in 'ActiveSupport::Callbacks#run_callbacks'
actionpack (8.1.4) lib/abstract_controller/callbacks.rb:266:in 'AbstractController::Callbacks#process_action'
actionpack (8.1.4) lib/action_controller/metal/rescue.rb:36:in 'ActionController::Rescue#process_action'
actionpack (8.1.4) lib/action_controller/metal/instrumentation.rb:76:in 'block in ActionController::Instrumentation#process_action'
activesupport (8.1.4) lib/active_support/notifications.rb:210:in 'block in ActiveSupport::Notifications.instrument'
activesupport (8.1.4) lib/ac

لأي شخص يواجه وضعاً مماثلاً، كانت طريقة العمل البديلة الفعالة التي سمحت بالوصول إلى المسؤول (admin) في نسخة discourse هي إنشاء حساب مستخدم مسؤول جديد باستخدام أمر rake create:admin بعد الدخول إلى التطبيق عبر ./launcher enter app

ومع ذلك، لا يحل هذا المشكلة الجذرية، حيث لا تزال حسابات المسؤولين الحالية ترحب بها صفحة خطأ العطل (Oops Error page) ولا يمكنها تسجيل الدخول بشكل طبيعي.

آمل أن يكون هناك إصلاح لهذه المشكلة في مرحلة ما، وأقدّر أي رؤى أو نصائح مسبقاً.


مواضيع محتملة ذات صلة:

في محاولة لتقديم حل غير متوقع باستخدام الميزات القياسية في Discourse، تساءلت عما إذا كان دمج حسابات المستخدمين قد يكون مفيدًا، على سبيل المثال: إنشاء حساب مدير جديد ثم دمجُه في حساب المدير القديم (يجب أن يتم هذا من قِبل الطاقم عبر وحدة التحكم).

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

هذا النوع من التفكير يشبه الانطلاق السريع من جانبي، ولم أجرب أيًا مما سبق، لكنني جربت نشر موضوع ثم تغيير ملكيته إلى حساب المستخدم المدير الذي قُفل بسبب الخطأ، فظهر إشعار post-notice new-user في Discourse على النحو التالي:

:tada: هذه أول مرة ينشر فيها [اسم المستخدم] — لنرحب به في الموقع!

يا إلهي، الأمر كأن حساب المدير لم يكن موجودًا حتى هذه اللحظة (تغيير الملكية).

هل يمكن أن يكون هذا مؤشرًا على شيء ما؟ :thinking:

لم أكن أُولي اهتمامًا لأنهما مجرد “تحذيرات”، لكن يظهر خطأ MaxMindDB في نفس الوقت، وقبل الخطأ المذكور أعلاه (ActiveVIEW::Tempalte::Error).

MaxMindDB (/var/www/discourse/vendor/data/GeoLite2-City.mmdb) could not be found: No such file or directory @ rb_sysopen - /var/www/discourse/vendor/data/GeoLite2-City.mmdb
MaxMindDB (/var/www/discourse/vendor/data/GeoLite2-ASN.mmdb) could not be found: No such file or directory @ rb_sysopen - /var/www/discourse/vendor/data/GeoLite2-ASN.mmdb

لقد لاحظت في تبويب ENV

Jobs::SuspiciousLogin

ربما هذا الخطأ غير القاتل في MaxMindDB، والذي يُعد تحذيرًا، هو ما يسبب حظر تسجيل دخول مستخدم الإدارة، ويعرض صفحة “Oops” لسبب ما أو كجزء من الخلل هنا؟

هل هذه حالة من مشاكل maxmind المُعدّة يدويًا بشكل خاطئ؟

يتم حظر الوصول إلى ملفات Maxmind في بعض المناطق. وقد لاحظت ذلك تحديدًا في الصين.

شكرًا لك، لكن خادم Discourse هذا ليس في الصين، كما أن موقع المستخدم المسؤول الذي يحاول تسجيل الدخول ليس كذلك أيضًا، ولا أعتقد أن قاعدة بيانات MaxMindDB تم إعدادها من قبل، أو إذا تم إعدادها جزئيًا، فلم يتم إكمالها.

أتذكر بشكل غامض إعدادات MaxMindDB في لوحة الإدارة، لكنني لا أجد أي شيء الآن.

لقد أدركت للتو شيئًا أيضًا: يجب أن تكون مسجل الدخول كمسؤول لرؤية /logs، لذا يمكن للمستخدم المسؤول المعني رؤية السجلات، ومن هناك يمكنه التنقل إلى /admin باستخدام رابط «العودة إلى الموقع»، لكنه يواجه كرات UFO النابضة (5 دوائر زرقاء)، لذا فهو على الأقل تجاوز صفحة «Oops» وإن كان بطريقة ملتوية، لكنه لم يدخل بعد. :thinking:

أرى في السجلات أن هذه النشاط الملتوِي يولّد المزيد من أخطاء OP.

ActionView::Template::Error (no implicit conversion of Array into String)

يتم إجراء الاتصال من الخادم، لذا فإن موقع الاتصال غير مهم - يستحق الأمر التحقق منه

حسنًا، لكن الخادم ليس في الصين.

كان ذلك مجرد مثال.

آه، نعم، بالطبع.. أوه! :grin: أنا فقط لست متأكدًا مما ينبغي التحقق منه في هذه الحالة.

@merefield @Ed_S @Falco المثال الوحيد الذي يمكنني العثور عليه لهذا الخطأ والذي يشبهه موجود هنا Error "no implicit conversion of Array into String" when using Gemini AI analysis on posts with images ربما كان يجب أن أنشر هذا الموضوع في قسم #contribute:bug؟

يبدو الأمر وكأنه يتعلق بعرض التغييرات القادمة - وهذا شيء لن يراه إلا المسؤولون. وفقًا لـ ask.discourse.com

يتم التحكم في الميزة بأكملها من خلال إعداد موقع مخفي يُسمى enable_upcoming_changes، وهو مُعيَّن على false في وحدة تحكم Rails:

SiteSetting.enable_upcoming_changes = false

ومع ذلك، يتطلب هذا الأمر الوصول إلى الطرفية/الخادم، لذا لا يمكن تنفيذه إلا في حالات التثبيت ذاتي الاستضافة.

شكرًا، قمت بتشغيل الأمر في rails console لكنه قال لي “الأمر غير موجود” :thinking:

حسنًا، آسف، يبدو أن نموذج اللغة قد أعطاني معلومات قديمة.

إليك بعض الأوامر التي جرّبتها واستخدمتها:

لجلب قائمة مستخدمين الإدارة (admin) وقيمة إعداداتهم المتعلقة بالتغييرات القادمة في جدول:

# docker exec -it app rails r 'User.where(admin: true).each { |u| puts "#{u.id} #{u.username} #{u.user_option.enable_upcoming_change_available_notifications}" }'
-1 system true
-2 discobot true
1 AdminTeam false

لتبديل الإعداد المعطى لمعرّف (id) محدد - في حالتي المعرّف هو 1:

# docker exec -it app rails r 'x=1;User.find(x).user_option.update!(enable_upcoming_change_available_notifications: !User.find(x).user_option.enable_upcoming_change_available_notifications)'

أفضّل طبعًا استخدام السطر الواحد من shell الجذر، وبالطبع يمكن الدخول إلى docker ثم إلى rails ثم تنفيذ الإجراءات إذا كان ذلك تفضيلك.

أشعر دائمًا ببعض الارتباك، فهل تقصد بـ root shell الدخول عبر الأمر ./launcher enter app ثم تنفيذ rails c؟

حسنًا، الناتج:

-1 system true

لا يوجد أي مشرفين قدامى أو جدد، ولا discobot، ولا أي شخص آخر مُدرج.

ربما هذه هي المشكلة، إذ يحتاج الأمر إلى تفعيله أو تطبيقه للمستخدم المشرف المعني. إن كان الأمر كذلك، فكيف أجد معرّفه (ID)؟

حسنًا، قمت بتشغيل الأمر مرة أخرى ووجدت المعرّف (id) وهو 1، لذا فإن الإعداد هو نفسه.

ومع ذلك، عند إدخال الأمر أدناه وتشغيله، يظهر الناتج => true

x=1;User.find(x).user_option.update!(enable_upcoming_change_available_notifications: !User.find(x).user_option.enable_upcoming_change_available_notifications)

نريد أن يكون الناتج false، أليس كذلك؟ لذلك لا أستطيع تحديد ما الذي يجب تغييره في ذلك الأمر. قرأت الأمر على أنه “بحث” فقط ولا شيء آخر، وهذا هو ناتج => true، وهو بالطبع غير مُطبَّق على المستخدم المستهدف.

أظن أنه كان ينبغي لي اتباع نهج أبسط…

# docker exec -it app rails r 'x=1;User.find(x).user_option.update!(enable_upcoming_change_available_notifications: false)'

وأمثلة مشابهة. لست متأكدًا من سبب عدم تفكيري في الأمر بهذه الطريقة.

أنا داخل التطبيق وفي rails c، ألصق ذلك فيظهر

=> true

لكنني تحققت منه وقد انعكس إلى false في المخرجات الجدولية.

جربت تسجيل الدخول، لكن لا يزال يظهر خطأ، ربما أحتاج إلى إعادة البناء؟

دعني أعود خطوة إلى الوراء… ما كنت أفعله هناك كان محاولة لتغيير تفضيلات المسؤول على أمل أن لا يحتاج الكود الذي يرمي الاستثناء إلى التنفيذ.

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

يؤدي سجل التتبع إلى هذا الكود في app/serializers/current_user_serializer.rb

  def has_new_upcoming_changes
    last_visited = object.custom_fields["last_visited_upcoming_changes_at"]
    return false if last_visited.blank? && object.created_at < Discourse.site_creation_date + 1.hour
    cutoff = last_visited.present? ? Time.zone.parse(last_visited) : object.created_at
    UpcomingChangeEvent.added.not_backfilled.where("created_at > ?", cutoff).exists?
  end

يمكنك تنفيذ استعلام في مستكشف البيانات لمعرفة القيمة التي تمتلكها حسابات المسؤول لديك لحقل last_visited_upcoming_changes_at.

SELECT 
    ucf.id AS custom_field_id, 
    ucf.user_id, 
    u.username,
    ucf.name, 
    ucf.value 
FROM user_custom_fields ucf
INNER JOIN users u ON u.id = ucf.user_id
WHERE ucf.name = 'last_visited_upcoming_changes_at'
  AND u.admin = true

وقد يكون ذلك مفيدًا. في حالتي (تم تحديثها مؤخرًا إلى v2026.7.3)، هي مجرد نص تاريخ، وهو ما أعتقد أنه يجب أن يكون كذلك.

شكرًا لك على هذا، حيث يُعاد الآن مع حقلي مخصّصين، لمستخدم الإدارة القديم نفسه، لكن كلا الإدخالات تحمل نفس قيمة الوقت:

| last_visited_upcoming_changes_at | 2026-09-22T10:30:47Z |
| last_visited_upcoming_changes_at | 2026-09-22T10:30:47Z |

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

| last_visited_upcoming_changes_at | 2026-10-02T08:23:22Z |


إصدار Discourse الحالي: 2026.10.0-latest