birchholt 직접 해보고 남기는 기록

languageCode 경고를 지우려고 locale로 바꿨더니 구버전 빌드에서 깨집니다

Hugo를 올린 뒤 빌드 로그에 languageCode가 deprecated(곧 없어질 예정)라는 경고가 뜨면, 대개 설정 파일의 languageCode를 locale로 바꿉니다. 경고 문구가 그렇게 하라고 하니까요.

오래된 열쇠와 새로 깎은 열쇠를 나란히 들고 두 개의 문 앞에서 망설이는 사람

설정 키 쪽 경고 문장은 이렇습니다(v0.165.0에서 재현).

WARN  deprecated: project config key languageCode was deprecated in Hugo v0.158.0 and will be removed in a future release. Use locale instead.

그런데 이 이름 바뀜 뒤로, 더 오래된 Hugo가 깔린 빌드 환경에서 can't evaluate field Locale로 배포가 멈췄다는 사례가 있습니다. 제 블로그도 v0.158.0의 이 변경을 한 번 밟았습니다. 그래서 무엇이 어디서 깨지는지를 버전별로 직접 빌드해서 확인했습니다. 2026-10-06에 Hugo v0.147.7, v0.157.0~v0.165.0 extended로 잰 값입니다.

경고가 처음부터 보이지는 않았습니다

처음엔 귓속말로, 몇 달 뒤엔 확성기로 같은 말을 전하는 마을 안내원

먼저 바뀐 내용입니다. v0.158.0(2026-03-16)에서 언어 관련 이름이 여럿 바뀌었는데, 단일 언어 사이트에 해당하는 건 설정 키 하나와 템플릿 메서드 둘입니다.

예전지금
설정 키 languageCodelocale
템플릿 .Site.LanguageCode.Site.Language.Locale
템플릿 .Language.LanguageCode.Language.Locale

v0.158.0 릴리스 노트의 Deprecations 절에 「languageCode → Use locale instead.」로 실려 있습니다. Hugo 포럼의 v0.158.0 deprecation 공지는 단일 언어 사이트라면 「change the languageCode key to locale」라고 적고 있습니다(2026-10-06 확인).

빈 Hugo 사이트에 languageCode = 'ko-kr' 한 줄을 두고 버전마다 빌드해 봤습니다. v0.158.0부터 v0.160.0까지는 기본 로그에 아무것도 안 나옵니다. --logLevel info를 붙여야 같은 문장이 INFO로 찍힙니다.

$ hugo --logLevel info    # v0.158.0
INFO  deprecated: project config key languageCode was deprecated in Hugo v0.158.0 ...

v0.161.0(2026-04-28)부터 WARN으로 올라옵니다. 공지에 적힌 순서 그대로입니다. 처음에는 info 로그로만 알리고, 약 3개월 뒤 경고로, 다시 약 12개월 뒤 오류로 올린다고 했습니다. 그러니 사이트는 그대로인데 “어제까지 조용하던 빌드에 이 경고가 생겼다"면, 먼저 Hugo 버전이 v0.161.0 이상으로 올라갔는지 보세요.

이 단계 설명은 위 공지의 「In about 3 months, the info log deprecation messages will be elevated to warnings, and about 12 months after that, they will be elevated to errors」입니다. v0.158.0·v0.159.0·v0.160.0은 기본 로그에 0줄, v0.161.0~v0.165.0은 WARN이었습니다. 오류로 바뀌는 버전은 아직 공지에 없습니다.

오류는 설정 키가 아니라 템플릿에서 납니다

새 서랍장 손잡이 자리를 찾지 못해 허공을 더듬는 오래된 장갑 낀 손

여기서 제가 예상과 다른 걸 봤습니다. locale = 'ko-kr'만 둔 설정으로 v0.157.0에서 빌드하면 오류가 안 납니다. 구버전은 모르는 키를 그냥 넘어갑니다.

오류가 나는 건 템플릿이 새 이름을 부를 때입니다. 홈 템플릿 한 줄을 이렇게 두고 빌드했습니다.

<html lang="{{ site.Language.Locale }}">
$ hugo    # v0.157.0
ERROR error building site: render: ... execute of template failed: template: home.html:1:15:
executing "home.html" at <site>: can't evaluate field Locale in type *langs.Language

v0.147.7에서도 같은 문장으로 멈췄고, v0.165.0에서는 <html lang="ko-kr">로 정상 출력됐습니다. Locale이라는 필드가 구버전 Hugo 안에 아예 없어서 템플릿을 실행하다 죽는 것입니다.

그러니 이 오류는 설정 키보다 템플릿이나 테마가 새 이름을 쓰기 시작했을 때를 먼저 의심해야 합니다. 테마가 새 이름으로 갈아탔는데 빌드 환경의 Hugo는 옛날 그대로인 경우입니다. 실제로 Cloudflare Pages에서 Blowfish 테마가 이 오류로 멈췄고 빌드 환경 변수 HUGO_VERSION을 0.161.1로 올려서 풀었다는 기록이 있습니다.

goodjinc.com의 기록(2026-05-21)입니다. Cloudflare Pages의 빌드 이미지 문서에는 Hugo 기본 버전이 v3 이미지 0.147.7, v2 이미지 0.118.2로 적혀 있습니다(2026-10-06 확인). 버전을 따로 지정하지 않으면 v3 이미지에서도 0.158.0보다 낮은 Hugo로 빌드됩니다.

반대 방향은 괜찮습니다. 새 Hugo는 옛 이름을 아직 받아 줍니다. v0.165.0에서 템플릿이 site.LanguageCode를 불러도 값은 ko-kr로 제대로 나오고 경고만 붙습니다. 새 Hugo는 옛 템플릿을 받아 주지만 옛 Hugo는 새 템플릿을 못 받습니다.

오류 없이 값만 바뀌는 쪽이 더 조용합니다

같은 모양의 편지 봉투 하나에서만 우표 귀퉁이가 살짝 잘려 나간 우편함

설정 키만 바꾼 경우로 돌아가겠습니다. 오류는 안 나는데, 그럼 아무 일도 없었을까요.

빈 사이트에서 Hugo 내장 RSS(구독용 글 목록 파일)의 <language> 값을 버전·설정별로 뽑았습니다.

버전languageCode만locale만둘 다
v0.147.7ko-krkoko-kr
v0.157.0ko-krkoko-kr
v0.165.0ko-kr (경고)ko-krko-kr (경고)

구버전에 locale만 주면 ko-kr이 조용히 ko가 됩니다. 키를 무시하니 언어 키(defaultContentLanguage = 'ko')를 그대로 쓰는 것으로 보입니다. 빌드는 성공하고 이 값이 바뀌었다는 경고는 한 줄도 없습니다.

제 블로그 사본으로도 해봤습니다. v0.157.0과 v0.147.7로 빌드하니 둘 다 성공했고 경고는 최소 버전이 안 맞는다는 줄 하나뿐이었습니다. 그리고 RSS에는 <language>ko가 들어 있었습니다. v0.165.0 빌드는 ko-kr입니다.

이 값이 실제로 어디에 닿는지도 봤습니다. Hugo 문서는 locale이 내장 alias 템플릿(옛 주소에서 새 주소로 보내 주는 페이지)의 lang, 내장 RSS의 language, 내장 Open Graph(공유 미리보기 정보)의 locale을 채운다고 적고 있습니다. 제 사이트는 셋 중 alias와 Open Graph를 직접 만든 템플릿으로 쓰기 때문에, 결과물에서 이 키가 닿는 곳은 RSS 한 줄뿐이었습니다. 내장 템플릿을 그대로 쓰는 사이트라면 닿는 곳이 셋으로 늘어납니다.

Hugo 설정 문서 locale 항목입니다(2026-10-06 확인). 내장 RSS 템플릿 40행이 v0.157.0에서는 site.Language.LanguageCode, v0.165.0에서는 site.Language.Locale을 읽습니다 — rss.xml (v0.165.0). 제 사본을 v0.165.0으로 languageCode 한 번, locale 한 번 빌드해 diff -r로 비교하니 결과물은 완전히 같았고 다른 건 경고 한 줄이었습니다.

제가 실제로 밟은 경고는 템플릿 한 줄이었습니다

현관 하나에만 다른 문패가 걸린 똑같은 집들이 늘어선 골목

제 설정 파일은 처음부터 locale = 'ko-kr'였습니다. 설정 키는 바꿀 일이 없었는데도 빌드할 때마다 경고가 한 줄 떴습니다. 출처는 직접 만든 alias 템플릿이었습니다.

<html lang="{{ or site.Language.LanguageCode site.Language.Lang }}">

그때 템플릿을 사본에서 되살려 v0.165.0으로 빌드하면 그대로 재현됩니다.

WARN  deprecated: .Language.LanguageCode was deprecated in Hugo v0.158.0 and will be removed in a future release. Use .Language.Locale instead.

경고만 문제가 아니었습니다. 이 템플릿을 쓰는 alias 페이지 10장만 lang=ko-kr이었고 나머지 24장은 공용 레이아웃에 적어 둔 lang="ko"였습니다. 한 사이트가 두 가지 언어 표기를 쓰고 있었습니다. 2026-09-22에 site.Language.Lang으로 바꿔 나머지 페이지와 맞췄고 그 뒤로 경고는 0줄입니다.

설정 키를 고쳤는데 경고가 남는다면 템플릿을 찾아보세요. 경고 문장의 앞부분이 project config key인지, .Site.LanguageCode·.Language.LanguageCode인지로 갈립니다. 테마를 쓰신다면 테마 폴더도 같이 찾아야 합니다. Blowfish와 PaperMod에도 같은 경고가 이슈로 올라와 있습니다.

$ grep -rn "LanguageCode" layouts/ themes/

Blowfish #3108은 language-redirect.html의 .Language.LanguageCode가 v0.166.0에서 경고를 낸다는 이슈이고, PaperMod #1870은 v0.162.0에서 같은 경고를 보고한 이슈입니다(2026-10-06 확인). Hugo 공지는 이런 위치를 찾을 때 hugo build --logLevel info를 돌리라고 안내합니다.

두 버전 모두 통과시키는 방법은 반쪽만 있었습니다

폭이 다른 두 개울을 한 장의 판자로 건너려다 판자 길이를 재 보는 사람

빌드 환경을 당장 올릴 수 없는 경우를 위해, 구버전과 신버전에서 모두 통과하는 방법을 찾아봤습니다.

템플릿은 됩니다. Hugo 버전을 보고 분기하면 실행되지 않는 쪽의 .Locale은 구버전에서도 오류를 내지 않았습니다.

{{- $code := site.Language.Lang -}}
{{- if ge hugo.Version "0.158.0" -}}
  {{- with site.Language.Locale }}{{ $code = . }}{{ end -}}
{{- else -}}
  {{- with site.LanguageCode }}{{ $code = . }}{{ end -}}
{{- end -}}
<html lang="{{ $code }}">

설정에 languageCode가 있으면 v0.147.7과 v0.157.0에서 오류 없이 ko-kr, v0.165.0에서는 locale 설정과 함께 경고 0줄로 ko-kr이 나왔습니다. 다만 구버전에 locale만 주면 템플릿이 오류는 안 내도 값은 ko가 됩니다. 아래 설정 키 문제가 그대로 남습니다. hugo.Version 비교는 글자 순서가 아니라 버전 번호로 됩니다. v0.147.7에서 ge hugo.Version "0.99.0"이 참으로 나왔습니다. 글자로 비교했다면 거짓입니다.

설정 키는 안 됩니다. 위 표에서 보듯 세 가지 선택지가 전부 한 군데씩 걸립니다.

둘 다 두면서 값이 다르면 v0.165.0에서는 locale 쪽이 이겼습니다(languageCode = 'en-us', locale = 'ko-kr'로 빌드하니 출력이 전부 ko-kr이었습니다). 옮겨 가는 동안 잠깐 둘 다 두는 건 쓸 만합니다. 하지만 경고 0과 구버전 호환을 설정 파일 하나로 동시에 얻는 방법은 찾지 못했습니다.

결국 고정해야 하는 건 빌드 환경의 Hugo 버전입니다

작업대 위 공구마다 같은 눈금자를 대어 맞추고 끈으로 묶어 두는 목수

그래서 제 결론은 키를 어떻게 적을지가 아니라 어느 Hugo로 빌드할지를 정해 두는 것입니다. 제 컴퓨터는 v0.165.0인데 빌드 서버가 v0.147.7이면, 오늘 본 오류와 값 바뀜이 전부 그 차이에서 나옵니다.

Cloudflare Pages가 직접 빌드한다면 프로젝트 설정의 환경 변수 HUGO_VERSION에 버전을 적으면 됩니다. 제 블로그는 GitHub Actions에서 빌드해 올리는데, 버전 숫자를 한 곳에만 둡니다. 빌드 스크립트 build.sh의 MIN이 그 한 곳이고 배포 워크플로가 이 값을 읽어서 그 버전을 내려받습니다. 스크립트는 그보다 낮은 Hugo면 빌드를 거부합니다.

MIN="0.165.0"
# ...
LOWEST="$(printf '%s\n%s\n' "$MIN" "$VER" | sort -V | head -1)"
if [ "$LOWEST" != "$MIN" ]; then
  echo "🔴 hugo $VER 은 최소 요구 버전 $MIN 보다 낮다." >&2
  exit 1
fi

설정 파일의 [module.hugoVersion] min만으로는 막히지 않습니다. 이번에 v0.157.0으로 빌드했을 때도 그 설정은 Module "project" is not compatible with this Hugo version 경고 한 줄만 내고 빌드는 끝까지 갔습니다. GitHub Actions로 빌드해 올리는 흐름은 이 글에, 버전을 올리다 템플릿 구조가 통째로 바뀐 경험은 v0.146 레이아웃 이전 글에 적어 두었습니다.

옮길 때 제가 따르는 순서는 이렇습니다.

  1. 경고 문장을 읽고 설정 키 경고인지 템플릿 경고인지 나눕니다
  2. 설정 키는 locale로, 템플릿은 .Language.Locale로 바꿉니다. 테마 폴더도 grep합니다
  3. 빌드 환경의 Hugo가 0.158.0 이상인지 확인하고 숫자로 고정합니다
  4. 고정할 수 없는 동안에는 설정에 두 키를 다 두고 직접 만든 템플릿은 버전 분기로 감쌉니다
  5. 바꾼 뒤에는 RSS의 <language>를 한 번 열어 봅니다. 오류 없이 바뀌는 건 거기였습니다