아바타 선택기 모달이 "t.split is not a function" 오류로 충돌합니다 (avatar-selector.gjs)

요약:
아바타 선택기 모달(프로필 아바타 변경용)을 열면 JavaScript 오류가 발생하며 팝업이 올바르게 작동하지 않습니다.

Discourse 버전: v2026.7.0-latest (커밋 59588b5d2a)
Ember 버전: v6.10.1

재현 단계:

  1. 사용자 프로필로 이동합니다.
  2. 아바타 변경 옵션을 클릭합니다.
  3. 아바타 선택기 모달이 열립니다 (스택 트레이스에 따르면 “해결됨” 이동 확인 모달 플로우를 통해 트리거됨)
  4. 브라우저 콘솔에 즉시 오류가 표시되고 모달이 올바르게 작동하지 않습니다.

기대되는 동작:
아바타 선택기가 정상적으로 열리고 사용자가 아바타를 선택하거나 업로드할 수 있어야 합니다.

실제 동작:
콘솔에 avatar-selector.gjsselectableAvatars getter 내부에서 TypeError: t.split is not a function가 발생합니다.

이미 수행한 문제 해결:

  • 모든 테마와 플러그인을 비활성화한 Safe Mode에서 테스트했으나 여전히 오류가 발생하므로, 이는 테마나 플러그인으로 인한 것으로 보이지 않습니다.

\\브라우저 / OS:\\ Brave Windows 11

\\콘솔 로그 / 스택 트레이스:\\

?safe_mode=no_themes,no_plugins:346  GET https://static.cloudflareinsights.com/beacon.min.js/v4513226cdae34746b4dedf0b4dfa099e1781791509496 net::ERR_BLOCKED_BY_CLIENT
app.js:365 ℹ️ Discourse v2026.7.0-latest — https://github.com/discourse/discourse/commits/59588b5d2a — Ember v6.10.1
avatar-selector.gjs:47 Uncaught (in promise) TypeError: t.split is not a function
at get selectableAvatars (avatar-selector.gjs:47:47)
at R (cache-DtDz7X5V.js:1647:15)
at index.js:87:32
at index.js:64:37
at zn (index.js:396:5)
at j (index.js:62:16)
at index-DaCZcoCY.js:4335:20
at index.js:64:37
at zn (index.js:396:5)
at j (index.js:62:16)
at index-DaCZcoCY.js:4335:20
at index.js:64:37
at zn (index.js:396:5)
at j (index.js:62:16)
at index.js:158:20
at index.js:64:37
at zn (index.js:396:5)
at j (index.js:62:16)
at Object.evaluate (index.js:1970:16)
at Object.evaluate (index.js:103:106)
at zb.evaluateSyscall (index.js:2873:20)
at zb.evaluateInner (index.js:2852:64)
at zb.evaluateOuter (index.js:2849:10)
at e.next (index.js:4167:45)
at e._execute (index.js:4157:21)
at e.execute (index.js:4133:41)
at _x.handleException (index.js:3450:19)
at bx.handleException (index.js:3592:52)
at hx.throw (index.js:3414:16)
at iy.evaluate (index.js:565:37)
at hx._execute (index.js:3401:34)
at hx.execute (index.js:3393:17)
at xx.rerender (index.js:3610:8)
at ww.render (index-DaCZcoCY.js:5211:23)
at index-DaCZcoCY.js:5409:16
at xb (index.js:2414:7)
at e.renderRoots (index-DaCZcoCY.js:5389:7)
at #o (index-DaCZcoCY.js:5374:12)
at e.revalidate (index-DaCZcoCY.js:5435:10)
at invoke (index.js:264:14)
at Rc.flush (index.js:180:11)
at zc.flush (index.js:334:19)
at pl._end (index.js:762:32)
at _boundAutorunEnd (index.js:499:12)
selectableAvatars @ avatar-selector.gjs:47
_getProp @ cache-DtDz7X5V.js:1647
(anonymous) @ index.js:87
(anonymous) @ index.js:64
track @ index.js:396
valueForRef @ index.js:62
(anonymous) @ index-DaCZcoCY.js:4335
(anonymous) @ index.js:64
track @ index.js:396
valueForRef @ index.js:62
(anonymous) @ index-DaCZcoCY.js:4335
(anonymous) @ index.js:64
track @ index.js:396
valueForRef @ index.js:62
(anonymous) @ index.js:158
(anonymous) @ index.js:64
track @ index.js:396
valueForRef @ index.js:62
(anonymous) @ index.js:1970
evaluate @ index.js:103
evaluateSyscall @ index.js:2873
evaluateInner @ index.js:2852
evaluateOuter @ index.js:2849
next @ index.js:4167
_execute @ index.js:4157
execute @ index.js:4133
handleException @ index.js:3450
handleException @ index.js:3592
throw @ index.js:3414
evaluate @ index.js:565
_execute @ index.js:3401
execute @ index.js:3393
rerender @ index.js:3610
(anonymous) @ index-DaCZcoCY.js:5211
(anonymous) @ index-DaCZcoCY.js:5409
inTransaction @ index.js:2414
renderRoots @ index-DaCZcoCY.js:5389
#o @ index-DaCZcoCY.js:5374
revalidate @ index-DaCZcoCY.js:5435
invoke @ index.js:264
flush @ index.js:180
flush @ index.js:334
_end @ index.js:762
(anonymous) @ index.js:499
Promise.then
(anonymous) @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_end @ index.js:768
(anonymous) @ index.js:499
Promise.then
(anonymous) @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_end @ index.js:768
(anonymous) @ index.js:499
Promise.then
(anonymous) @ index.js:18
flush @ index.js:29
_scheduleAutorun @ index.js:928
_ensureInstance @ index.js:919
ensureInstance @ index.js:731
scheduleRevalidate @ index-DaCZcoCY.js:4146
dirtyTag @ index.js:229
dirtyTagFor @ index.js:848
setter @ index.js:871
set @ cache-DtDz7X5V.js:1886
show @ modal.js:57
await in show
showAvatarSelector @ account.js:43
_join @ index.js:788
join @ index.js:605
join @ index.js:152
(anonymous) @ route-action.js:48
(anonymous) @ index.js:2534
(anonymous) @ d-button.gts:216
invoke @ index.js:264
flush @ index.js:180
flush @ index.js:334
_end @ index.js:762
end @ index.js:565
_runExpiredTimers @ index.js:869
setTimeout
setTimeout @ index.js:39
_installTimerTimeout @ index.js:912
_reinstallTimerTimeout @ index.js:896
_later @ index.js:829
later @ index.js:652
next @ index.js:562
_triggerAction @ d-button.gts:213
click @ d-button.gts:167
2개의 좋아요

이 문제를 meta에서 재현할 수 있나요?

위 오류 메시지는 사용자의 인스턴스에서 발생한 것인가요? 그리고 Cloudflare를 사용 중인가요? 이 부분이 그렇다고 시사하는 것 같습니다.

1개의 좋아요

안녕하세요,

답변해 주시고 문제를 지적해 주셔서 감사합니다.

질문에 대한 답변을 드리자면: 아니요, meta.discourse.org 자체에서는 재현할 수 없으며 제 포럼에서만 재현됩니다.

Cloudflare에 대해 말씀드리면: 네, 제 포럼은 Cloudflare 뒤에 있습니다. 하지만 해당 콘솔 라인(beacon.min.js / ERR_BLOCKED_BY_CLIENT)은 실제 버그와 무관합니다. 이는 Brave Shields가 Cloudflare의 분석 스크립트를 차단하기 때문에 발생하는 것입니다. Brave Shields를 완전히 비활성화하면 해당 라인은 사라지지만, 아바타 선택기 오류(TypeError: t.split is not a function)는 여전히 동일한 방식으로 발생합니다.

참고로, 저는 거의 3년 동안 포럼을 Cloudflare 뒤에 두고 운영해 왔으며, 지금까지 프로필 아바타 변경은 항상 정상적으로 작동했습니다. 따라서 이는 오래된 Cloudflare 관련 문제라기보다 회귀(regression) 문제로 보입니다.

meta에서는 재현되지 않으므로 제 환경 설정의 특정 사항과 관련이 있을 수 있습니다. 문제를 좁히기 위해 도움이 될 설정이나 로그를 확인하는 데 기꺼이 협력하겠습니다. 확인하면 유용할 것(예: “선택 가능한 아바타” 사이트 설정 값, 또는 스택 트레이스에서 이 모달의 트리거로 나타나는 Solved 플러그인과 관련된 항목 등)이 있으면 알려주세요.

확인해 주셔서 감사합니다.

2개의 좋아요

네, 맞아요. Cloudflare 때문은 아닐 것 같아요.

다른 인스턴스에서 이 문제를 테스트해 봤는데, 선택 가능한 아바타만 활성화했습니다. 두 개의 아바타를 업로드해야 했어요(사이트 설정 요구 사항) 그리고 활성화했습니다.

이 두 설정을 수정해 보시고, 그쪽에서 어떤 변화가 있는지 확인해 주시겠어요?

2개의 좋아요

안녕하세요,

이 문제를 조사해 주셔서 감사합니다. 말씀하신 대로 옳았습니다.

제안해 주신 대로 “선택 가능한 아바타” 설정에 아바타 두 개를 업로드한 결과, 오류가 사라졌습니다. 이제 아바타 선택기가 정상적으로 열리고 작동합니다.

즉, 근본 원인은 다음과 같습니다. “선택 가능한 아바타” 기능이 활성화되어 있지만 업로드된 아바타 수가 필요한 수보다 적거나(또는 비어 있는 경우) 모달이 정상적으로 실패하지 않고 충돌한다는 것입니다. 제 경우에는 아바타를 하나도 업로드하지 않은 채로 설정이 활성화되어 있어 t.split is not a function 오류가 발생했습니다.

여전히 이 문제는 코어 측면에서 수정할 가치가 있다고 생각합니다. 설정이 잘못 구성되었더라도 모달이 포착되지 않은 TypeError를 발생시켜 아바타 선택 기능을 완전히 깨뜨려서는 안 됩니다. 이상적으로는 다음과 같은 방식으로 처리되어야 합니다.

  • 목록이 비어 있거나 유효하지 않을 경우, “선택 가능한 아바타” 기능을 건너뛰고 일반적인 아바타 선택으로 폴백하거나
  • 조용한 JS 충돌 대신 명확한 검증 오류를 표시

이 문제를 좁히는 데 도움을 주셔서 다시 한번 감사합니다.

2개의 좋아요

네, 맞는 말씀이네요. 수정을 제출해 보시겠어요? 관련해서 잘 아시면 이 부분에 대한 Pull Request를 기꺼이 받아들이겠습니다.

1개의 좋아요

저는 소프트웨어 개발을 하고 있지만, 이런 종류의 작업에는 경험이 많지 않습니다. 그래서 직접 수정을 제출할 때 틀릴까 봐 조금 망설여집니다. 핵심 팀에서 이어서 진행해 주시면 좋겠습니다. 원하시면 GitHub에 이슈를 열어 두겠습니다.

3개의 좋아요

문제가 아닙니다. 이렇게 하면 해결될 것 같습니다: DEV: Fix JS error in modal when selected avatars is misconfigured - Pull Request #41663 - discourse/discourse - GitHub

3개의 좋아요