커스텀 콘텐츠가 있는 플래그 제출 시 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개의 좋아요

보고해 주셔서 감사합니다. 확인해 보겠습니다. 원하시는 경우 PR을 보내 주셔도 됩니다.

로컬에서 재현을 시도해 보았으나 실패했습니다. safe-mode를 활성화하면 이 문제를 재현할 수 있나요?

1개의 좋아요

주제를 한 번만 플래그를 지정하면 already_did_flaggingfalse여야 하므로 이 문제가 발생하지 않을 것이라고 생각합니다. 일반적으로 동일한 게시물에 다시 플래그를 지정하는 것은 불가능합니다. 하지만 "기타"로 플래그를 지정한 후에도 "불법"으로 플래그를 지정할 수 있습니다. 이 경우의 결과는 다음과 같습니다.

1개의 좋아요

이제 성공적으로 재현했습니다:

보통 같은 게시물을 두 번 플래그를 지정하는 것은 불가능하지만, 중첩된 주제에서는 상황이 다른 것 같습니다. 따라서

  1. 몇 가지 중첩된 답변이 포함된 주제를 생성합니다
  2. 답변에 “기타” 플래그를 지정하고 제출합니다
  3. 플래그 아이콘을 다시 클릭합니다
    기대 결과: 중첩 모드가 없는 주제 내 게시물과 마찬가지로 “불법” 옵션만 사용 가능합니다.
    실제 결과: "기타"를 제외한 모든 플래그 이유가 사용 가능합니다.
  4. 다른 이유를 선택하고 플래그를 제출한 후 브라우저 콘솔을 확인합니다
1개의 좋아요

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

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

1개의 좋아요

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

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


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

1개의 좋아요

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

1개의 좋아요

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


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

1개의 좋아요

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