커스텀 콘텐츠가 있는 플래그 제출 시 TypeError 발생 (require_message 플래그)

버그 설명

사용자가 커스텀 메시지가 필요한 플래그 유형(예: notify_moderators, notify_user, 또는 "메시지 필수"가 활성화된 관리자 생성 커스텀 플래그)을 선택하고 메시지를 입력한 후 제출하면 브라우저에서 처리되지 않는 TypeError가 발생하며 플래그가 제출되지 않습니다.

재현 단계

  1. 임의의 토픽 게시글을 방문합니다.
  2. 플래그 모달을 열기 위해 플래그 버튼을 클릭합니다.
  3. 메시지가 필요한 플래그 유형을 선택합니다(예: “기타” / notify_moderators, 또는 "메시지 필수"가 활성화된 관리자 → 플래그에서 생성된 모든 커스텀 플래그).
  4. 텍스트 영역에 메시지를 입력합니다(최소 길이를 통과할 만큼 충분히 길게).
  5. 제출 버튼을 클릭합니다.

기대되는 동작

플래그가 성공적으로 제출됩니다.

실제 동작

플래그 모달은 닫히지만 플래그는 제출되지 않습니다. 브라우저 콘솔에는 다음과 같은 내용이 표시됩니다:

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
}

PostFlagpostActionForactions_summary 내에서 숫자 id로 선택된 플래그를 조회합니다:

// post-flag.js
postActionFor(flagModal) {
  return flagModal.args.model.flagModel.actions_summary.find(
    (item) => item.id === flagModal.selected.id
  );
}

백엔드 PostSerializercan_act, count, 또는 acted 중 적어도 하나가 참일 때만 actions_summary에 플래그 항목을 포함합니다:

result << summary if summary[:can_act] || summary[:count] || summary[:acted]

require_message: true 플래그(모두 notify_type: true인 경우)의 경우, post_can_act?already_did_flagging이 참일 때 can_act: false로 설정합니다. 즉, 사용자가 해당 게시글에 이전에 notify 유형 플래그를 제출한 경우입니다. 이 경우 항목은 actions_summary에 존재하지 않으며, postActionForundefined를 반환하고 크래시가 발생합니다.

한편, UI에서 사용자가 선택할 수 있는 것을 제어하는 Post#flagsAvailable은 페이지 로드 시점에 구축된 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#postActionForidactions_summary를 검색하는 대신 name_key를 키로 사용하는 actionByName 맵을 사용해야 합니다. 이는 TopicFlag#postActionFor가 이미 작동하는 방식과 일치합니다:

// post-flag.js
postActionFor(flagModal) {
  return flagModal.args.model.flagModel.actionByName[
    flagModal.selected.name_key
  ];
}

그리고 notifyModeratorsFlagid가 아닌 name_key로 비교해야 합니다:

get notifyModeratorsFlag() {
  return this.flagsAvailable.find((f) => f.name_key === NOTIFY_MODERATORS_KEY);
}

Discourse 버전

2026.5.0-latest

재현 가능 환경

  • 최신 main 브랜치
2개의 좋아요

Thanks for reporting, we will have a look, feel free to shoot through a PR as well if you want.

I tried to reproduce locally but am unsuccessful. Are you able to reproduce this if you enable safe-mode?

1개의 좋아요

I think flagging the topic once won’t cause this because then already_did_flagging should be false. Usually flagging the same post again is not possible. But after flagging as “something else” you can still flag as “illegal”. The result in this case is

1개의 좋아요

Now I had a successful repro:

While flagging the same post twice is usually not possible, this seems to be different in nested topics. So

  1. create a topic with some nested replies
  2. Flag the reply as “something else” and submit the flag
  3. Click the flag icon again
    Expected result: only “It’s illegal” is available just like on posts in topics without nested mode.
    Actual result: All flagging reasons except for “something else” are available.
  4. Choose another reason, submit the flag and check the browser console
1개의 좋아요

늦었지만 지금 이 문제를 작업하고 있습니다.

중첩 모드와 비중첩 모드 모두에서 "it’s illegal"이 보이지 않습니다. 중첩 모드를 비중첩 토픽의 동작과 일치하도록 수정했지만, 다시 신고를 시도하면 둘 다 다음과 같이 보입니다:

1개의 좋아요

위에서 설명한 단계를 중첩된 답변이 없는 주제에서 그대로 따라 해 보았습니다.

아래 모달에서 볼 수 있듯이, 해당 게시물은 이미 사용자가 신고하여 모더레이션 대상이 된 상태이며, 신고 모달을 다시 클릭하면 다음과 같은 결과가 나타납니다:


사이트 설정을 살펴본 결과, allow_all_users_to_flag_illegal_content 설정이 다른 옵션을 선택한 후에도 사용자가 여전히 illegal로 신고할 수 있게 하는 원인이 될 수 있을 것 같습니다.

1개의 좋아요

아, 그게 문제였군요! 감사합니다. 수정이 곧 배포될 예정입니다.

1개의 좋아요

메인 버그의 수정이 이제 latest에 포함되어 있으며, 해당 문제를 해결해야 합니다. 즉, 중첩되지 않은 토픽 답변과 동일해야 합니다.


이것은 다른 동작을 하므로 분리했으며, 이 부분도 곧 수정할 예정입니다.

1개의 좋아요

후속 작업도 병합되었습니다. 깨진 비교 로직은 사실 우리에게 유리하게 작용하고 있었습니다 — 비교 로직을 제대로 수정하면 관리자/모드가 이유 없이 플래그를 제출할 수 있게 되기 때문입니다. 플래그 제출 시 이유가 필수적이기를 원하므로, 향후 혼란을 피하기 위해 로직을 수정하는 대신 해당 코드를 제거했습니다.