한 줄 결론. Blogger API가 한국어 title을 깨진 채로 받아들여도 사용자에게 어떤 silent reject 신호도 주지 않습니다. 응답이 HTTP 200 ok=true라도 라이브에 mojibake가 보이면, 발행 자동화 스크립트의 mojibake 검사 조건이 특정 환경에서만 작동하는지 의심하세요.
문제 상황
내가 운영하는 한국어 블로그에 글 한 편을 자동화 스크립트로 patch했습니다. 응답은 분명히 HTTP 200 + ok=true였습니다. 하지만 라이브 페이지를 열어보니 title 부분만 깨진 문자가 박혀있었습니다. 본문은 정상이었습니다.
에러 증상
- 라이브 페이지
<title>태그 = mojibake (예:테안녕) - Blogger Admin 화면에서도 동일하게 깨진 title
- API 응답 자체는 정상 — 어떤 에러도 없음
- 본문은 정상 한국어로 patch 완료
환경
- Python 3.12 + requests 2.31
- Blogger v3 API + Google OAuth
- 발행 자동화 스크립트 (글 patch 전용 endpoint)
시도했지만 실패한 방법
- 같은 title로 다시 patch — 동일 mojibake 재현
- 다른 환경에서 patch — 동일 결과
- title을 Blogger Admin에서 직접 수정하면 됨 (즉 API 경로 안에서 문제)
원인
운영 기록 기준 정확히 확인된 root cause: 발행 자동화 스크립트 안에 mojibake 자동 복구 검사가 박혀있었는데, 그 검사가 특정 블로그 ID 조건으로만 작동하도록 좁혀져 있었습니다. 다른 블로그에서 patch를 호출하면 검사 자체가 건너뛰어져, mojibake title이 그대로 Blogger API에 PATCH됩니다.
왜 mojibake가 처음 만들어졌는지는 별개 이슈(백업 경로의 더블 UTF-8 인코딩)였지만, 진짜 위험은 발행 스크립트가 그걸 검증 없이 통과시킨 부분이었습니다.
최종 해결
두 위치에 mojibake auto-revert 박았습니다.
# 1) 글 patch endpoint의 검사 gate에서 블로그 ID 조건 제거
if hooks.get("mojibake_fix", True) and not is_multilingual:
# ... 복구 helper 실행
# 2) 글 publish endpoint에 title-only mojibake 자동 복구 추가
mb_chars = sum(1 for ch in title if 0xC0 <= ord(ch) <= 0xFD)
if mb_chars >= 4:
fixed, hb, ha, segs = mojibake_reverse(title, ...)
if segs > 0 and ha > hb:
body = body.model_copy(update={"title": fixed})
검증 결과
운영 기록 기준 검증:
- fix 적용 후 임의 mojibake title을 일부러 patch 시도 → 검사가 자동 reverse + log warning
- 기존 사고 글의 title도 정상 한국어로 복구됨
- 다국어(외국어) 글은 영향 안 받음 — 검사가 외국어를 정상 처리
현재 상태
fixed. 모든 블로그에서 mojibake 검사 작동. publish 단에도 안전망이 있어 외부 script가 mojibake를 보내도 차단됩니다.
같은 문제 겪는 분들에게
- 응답이 정상이어도 라이브 페이지를 직접 확인: HTTP 200이 데이터 정합성을 보장하지 않습니다.
- 검사 조건을 좁히는 건 신중하게: 특정 환경에만 검사하도록 좁힌 옛 코드가 다른 환경에서 사고의 root cause가 됩니다.
- 입력 검증 위치는 가장 바깥쪽: 자동화 endpoint 진입점에서 한 번 거르면 내부 어떤 path를 통과해도 mojibake가 못 빠져나갑니다.