라떼군 이야기


워드프레스 6.7 업데이트 후 '_load_textdomain_just_in_time' Notice 에러 원인과 해결 방법

Problem

워드프레스(WordPress)를 버전 6.7로 업데이트한 이후, 웹사이트 화면이나 에러 로그에 Notice: Function _load_textdomain_just_in_time was called incorrectly.라는 PHP Notice가 발생하는 경우가 많습니다. 이 에러는 특정 플러그인이나 테마에서 번역(Translation) 파일을 너무 일찍 불러오려고 할 때 발생합니다. 에러 메시지에는 문제가 되는 텍스트 도메인(예: blahblah)이 명시되며, 사이트 운영자나 플러그인 개발자 모두에게 흔하게 나타나는 문제입니다.

Background

워드프레스 6.7 버전에서는 다국어 처리(i18n)와 관련된 성능 및 로직 개선이 대대적으로 이루어졌습니다. 이 과정에서 번역 텍스트 도메인(Text Domain)을 로드하는 시점에 대한 엄격한 기준이 새롭게 적용되었습니다. 과거에는 plugins_loaded 훅(Hook)이나 그 이전 단계에서 번역 파일을 로드해도 큰 문제가 없었지만, 6.7 버전부터는 반드시 init 훅 또는 그 이후에 로드해야 합니다. 즉, 워드프레스 코어가 완전히 준비되기 전에 __()load_plugin_textdomain() 같은 번역 관련 함수가 실행되면 코어에서 이를 감지하고 경고 메시지를 출력하게 됩니다.

Solution

이 문제는 당신이 일반 웹사이트 운영자인지, 아니면 플러그인/테마 개발자인지에 따라 해결 방법이 다릅니다.

1. 일반 웹사이트 운영자인 경우

가장 먼저 해야 할 일은 사용 중인 모든 테마와 플러그인을 최신 버전으로 업데이트하는 것입니다. 대부분의 활발히 유지보수되는 플러그인 개발자들은 이미 이 문제를 인지하고 패치를 배포했을 가능성이 높습니다. 만약 업데이트 후에도 문제가 지속된다면, 에러 메시지에 포함된 텍스트 도메인(예: Translation loading for the blahblah domain)을 확인하여 해당 플러그인/테마 개발자에게 버그 리포트를 보내는 것이 좋습니다.

2. 플러그인 및 테마 개발자인 경우

텍스트 도메인을 등록하는 함수(load_plugin_textdomain, load_theme_textdomain 등)가 실행되는 훅(Hook)의 위치를 확인해야 합니다. 기존에 plugins_loaded를 사용했다면 이를 init으로 변경해야 합니다.

잘못된 예시 (수정 전):

// 워드프레스 6.7 이전에는 동작했지만, 이제는 Notice를 발생시킵니다.
add_action('plugins_loaded', function()
{
    // 번역 파일을 너무 일찍 로드하고 있습니다.
    load_plugin_textdomain('your-textdomain', false, '/path/to/your/plugin/languages/');
});

올바른 예시 (수정 후):

// 'init' 훅을 사용하여 워드프레스 코어가 준비된 후 로드합니다.
add_action('init', function()
{
    load_plugin_textdomain('your-textdomain', false, '/path/to/your/plugin/languages/');
});

또한, init 훅 이전에 get_plugin_data 함수를 사용하고 있다면, 세 번째 파라미터(번역 여부)로 false를 전달하거나 해당 로직 자체를 init 훅 이후로 이동시켜야 합니다.

3. 에러 발생 위치를 찾는 디버깅 방법 (고급)

어떤 파일의 몇 번째 줄에서 번역 함수가 잘못 호출되었는지 찾기 어렵다면, 워드프레스 코어 파일을 임시로 수정하여 스택 트레이스(Stack Trace)를 로그로 남길 수 있습니다.

wp-includes/l10n.php 파일을 열고 _load_textdomain_just_in_time 함수(약 1350번째 줄)를 찾은 뒤, _doing_it_wrong() 함수가 호출되기 직전에 아래 코드를 삽입하세요.

// '[textdomain]' 부분을 에러가 발생한 실제 텍스트 도메인 이름으로 변경하세요.
if ($domain == "[textdomain]") {
    // 버퍼링을 시작하여 백트레이스 문자열을 캡처합니다.
    ob_start();

    // 인자 값을 무시하여 로그가 너무 길어지는 것을 방지합니다.
    debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

    // 캡처한 백트레이스 내용을 가져오고 버퍼를 비웁니다.
    $trace = ob_get_clean();

    // 로그 메시지 포맷팅
    $log_message = "ERROR: Early textdomain call for '" . $domain . "'\n";
    $log_message .= "Stack Trace:\n" . $trace . "\n";
    $log_message .= "--------------------------------------------------\n";

    // 서버의 PHP 에러 로그 파일에 메시지를 기록합니다.
    error_log($log_message);
}

코드를 저장하고 페이지를 새로고침한 뒤 PHP 에러 로그를 확인하면, 어떤 테마나 플러그인의 특정 파일에서 번역 함수를 일찍 호출했는지 정확한 경로와 줄 번호를 파악할 수 있습니다.

Deep Dive

앞서 소개한 wp-includes/l10n.php 코어 파일을 수정하는 디버깅 방식은 매우 강력하지만, 반드시 로컬 개발 환경이나 스테이징 환경에서만 임시로 사용해야 합니다. 프로덕션(운영) 환경에서 코어 파일을 직접 수정하는 것은 보안 및 유지보수 측면에서 매우 위험하며, 디버깅이 끝난 후에는 수정한 파일을 반드시 원상 복구해야 합니다.

또한, 클래스 속성(Property)이나 전역 배열을 선언할 때 __('text', 'domain') 함수를 직접 할당하는 경우에도 문제가 발생할 수 있습니다. 파일이 인클루드(Include)되는 시점에 함수가 즉시 실행되기 때문입니다. 번역이 필요한 문자열은 클래스 프로퍼티에 직접 할당하지 말고, init 훅 이후에 실행되는 메서드 내부에서 할당되도록 지연(Lazy loading)시키는 패턴을 사용하는 것이 좋습니다.

Conclusion

워드프레스 6.7의 _load_textdomain_just_in_time Notice는 다국어 번역 파일 로딩 시점을 최적화하기 위한 코어 업데이트의 결과입니다. 웹사이트 운영자는 테마와 플러그인을 최신 버전으로 유지하여 문제를 해결할 수 있으며, 개발자는 텍스트 도메인 로드 및 번역 함수 호출 시점을 반드시 init 훅 이후로 조정해야 합니다. 올바른 훅의 사용은 워드프레스 생태계의 전반적인 성능 향상과 안정성에 기여합니다.

References

협업 및 후원 연락하기 →