Blogger 테마 silent reject 사고 — 라이브에 안 반영되는 이유를 사흘 만에 찾은 사연

2 min read · 583 words

활용 팁 / 블로그 운영 / 디버깅 스토리
약 1,600자

테마 XML 을 업로드하면 Blogger UI 가 "테마가 업데이트되었습니다" 토스트를 띄웁니다. 그런데 라이브 페이지를 새로고침해도 변경이 안 반영됩니다. 우리는 이 silent reject 사고를 사흘 동안 추적했고, 원인은 한 글자였습니다. 같은 사고 겪을 분께 추적 과정을 그대로 풀어 둡니다.

사고 발생

테마에 새 hero 섹션을 추가한 후 CDP 자동 업로드 모듈로 업로드. UI 응답은 정상 "업데이트 완료" 토스트. 그런데 라이브 페이지 새로고침 → 옛 테마 그대로. cache 일 거라 생각하고 5분 기다림. 변함없음.

수동 업로드 시도. Blogger 관리자 → 테마 → 백업/복원 → XML 파일 업로드. UI 응답 동일 "업데이트 완료". 라이브 변함없음.

다른 컴퓨터에서 시크릿 모드로 라이브 fetch → 옛 테마. 사장님 cache 가 아니었습니다.

추적 1단계 — round-trip 검증

CodeMirror 편집기 (Blogger 의 테마 소스 코드 수정 화면) 에서 getValue() 호출해서 방금 우리가 보낸 XML 과 비교. 결과: byte-for-byte 다름. Blogger 가 우리 XML 의 일부를 silent 하게 잘라냈습니다. 그러나 UI 는 toast 만 띄우고 reject 사실을 안 알림.

이걸 발견하기까지 한나절. silent reject 가 있다는 사실 자체를 모르고 있었습니다.

추적 2단계 — diff

우리가 보낸 XML 과 Blogger 가 저장한 XML 의 diff. 차이가 난 부분 = 안의 CDATA 섹션. 우리 새 CSS 주석 안에 이런 텍스트가 박혀 있었습니다.


/* sess113 antigravity light hero — applies to <body class="ag-home"> only */

평범한 CSS 주석. 그런데 그 안의 텍스트가 Blogger 의 SkinVariables 파서를 깨뜨렸습니다.

원인 — Blogger CDATA 파서의 quirk

Blogger 의 테마 엔진은 안에 CSS 를 담습니다. 일반적으로 CDATA 안에 무엇이 들어가도 안전합니다. 그런데 Blogger 의 SkinVariables 파서는 CDATA 안의 CSS 주석 안의 텍스트도 스캔해서 HTML 토큰 (, , 등) 을 발견하면 reject 합니다.

이건 Blogger 의 안전망 (XSS 방어 추정) 이지만, 사용자에게 reason 을 안 알려줍니다. UI 는 toast 만 띄움.

해결

CSS 주석 안의 HTML 토큰을 모두 자연어로 swap.

수정 전:


/* applies to <body class="ag-home"> only */

수정 후:


/* applies to home body when ag-home class is set */

업로드 → 라이브 즉시 반영. 사흘 만에 풀린 사고였습니다.

예방 — lint pass

이후 우리는 모든 theme.xml 패치 전에 자동 lint 를 박았습니다.


import re

DANGEROUS_TOKENS = [
 r'<html\b', r'<body\b', r'<head\b',
 r'<a\s+id\s*=',
 r'<script\b', r'<iframe\b',
]

def lint_skin_cdata(xml: str) -> list[str]:
 """b:skin CDATA 안 CSS 주석에서 위험 토큰 detect."""
 findings = []
 skin_m = re.search(r'<b:skin>\s*<!\[CDATA\[(.*?)\]\]>\s*</b:skin>',
 xml, re.DOTALL)
 if not skin_m:
 return findings
 css = skin_m.group(1)
 # CSS 주석 추출 (/* ... */)
 for cm in re.finditer(r'/\*.*?\*/', css, re.DOTALL):
 comment = cm.group(0)
 for tok in DANGEROUS_TOKENS:
 if re.search(tok, comment, re.I):
 findings.append(f"line {comment.count(chr(10))}: {tok}")
 return findings

bad = lint_skin_cdata(open("theme.xml", encoding="utf-8").read())
if bad:
 raise SystemExit(f"silent-reject risk: {bad}")

CDP 자동 업로드 스크립트에 이 함수를 첫 줄에 박았습니다. 발견 시 abort. silent reject 재발 0건.

따라하실 분께

Blogger 테마를 다루신다면 CSS 주석 안에 raw HTML 태그 토큰 절대 박지 마세요. 자연어 설명으로 풀어 쓰세요. Blogger 의 silent reject 는 한 글자 때문에 작업 흐름을 통째로 망가뜨립니다.

요약: silent reject 신호는 "UI 정상 + 라이브 미반영". round-trip 검증 (CodeMirror.getValue()) 으로 빠르게 진단. 원인은 거의 CDATA 안 CSS 주석의 HTML 토큰. lint 한 번이면 평생 예방됩니다.

Category Coverage Notice

This article follows our label-specific editorial criteria. Details:

ToolSignal Pro Editorial

ToolSignal Pro는 AI·IT·소프트웨어 트렌드를 다루는 종합 IT 인사이트 매거진입니다.

이전 글 다음 글