バグの説明
ユーザーがカスタムメッセージを必要とするフラグタイプ(例:notify_moderators、notify_user、または「メッセージ必須」が有効な管理者作成のカスタムフラグなど)を選択し、メッセージを入力して送信すると、ブラウザで未処理の TypeError が発生し、フラグが送信されません。
再現手順
- 任意のトピック投稿にアクセス
- フラグボタンをクリックしてフラグモーダルを開く
- メッセージを必要とするフラグタイプを選択(例:「その他」/
notify_moderators、または「管理者 → フラグ」で「メッセージ必須」が有効なカスタムフラグ) - テキストエリアにメッセージを入力(最小長さを満たす長さ)
- 送信ボタンをクリック
期待される動作
フラグが正常に送信される。
実際の動作
フラグモーダルは閉じるが、フラグは送信されない。ブラウザコンソールには以下が表示される:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'act')
at n.create (flag.js:24:8)
at S.createFlag (flag.gjs:205:32)
at S.takeAction (flag.gjs:196:12)
at m.perform (reviewable-bundled-action.gjs:47:17)
at ej._boundaryActionHandler (select-kit.js:685:34)
...
根本原因の分析
クラッシュは Flag#create(flag.js:24)で発生している:
create(flagModal, opts) {
const postAction = this.postActionFor(flagModal); // undefined を返す
// ...
postAction.act(...) // ← TypeError: Cannot read properties of undefined
}
PostFlag 内の postActionFor は、actions_summary 内で数値の id によって選択されたフラグを検索する:
// post-flag.js
postActionFor(flagModal) {
return flagModal.args.model.flagModel.actions_summary.find(
(item) => item.id === flagModal.selected.id
);
}
バックエンドの PostSerializer は、can_act、count、acted のいずれかが真である場合のみ、actions_summary にフラグエントリを含める:
result << summary if summary[:can_act] || summary[:count] || summary[:acted]
require_message: true のフラグ(すべて notify_type: true)の場合、already_did_flagging が真(つまり、ユーザーがその投稿に対して以前に通知タイプのフラグを提出している)であると、post_can_act? は can_act: false に設定する。その場合、エントリは actions_summary に存在せず、postActionFor は undefined を返し、クラッシュが発生する。
一方、Post#flagsAvailable(UI でユーザーが選択できるものを制御)は、ページ読み込み時に構築された actionByName マップを使用するため、actions_summary にエントリが存在しなくなっても、フラグは引き続き選択可能として表示される。
副次的なバグ
flag.gjs には、比較が破綻している箇所もある:
const NOTIFY_MODERATORS_KEY = "notify_moderators"; // 文字列
get notifyModeratorsFlag() {
return this.flagsAvailable.find((f) => f.id === NOTIFY_MODERATORS_KEY);
// ^ 数値 ^ 文字列 — 常に false
}
f.id は数値だが NOTIFY_MODERATORS_KEY は文字列であるため、=== は常に false を返し、notifyModeratorsFlag は常に undefined になる。これにより、flagForReview() 内の「レビュー用にフラグ」ボタンのロジックが破綻する。
提案される修正
PostFlag#postActionFor は、TopicFlag#postActionFor がすでに採用している方法と同様に、id による actions_summary の検索ではなく、name_key をキーとする actionByName マップを使用すべきである:
// post-flag.js
postActionFor(flagModal) {
return flagModal.args.model.flagModel.actionByName[
flagModal.selected.name_key
];
}
また、notifyModeratorsFlag は id ではなく name_key で比較すべきである:
get notifyModeratorsFlag() {
return this.flagsAvailable.find((f) => f.name_key === NOTIFY_MODERATORS_KEY);
}
Discourse バージョン
2026.5.0-latest
再現環境
- 最新の
mainブランチ