The Blogger Theme Silent Reject Incident — How We Found Why Live Wasn't Updating After Three Days

#223

The Incident: A Complete Silent Reject Story on Blogger Themes

When operating a customized Blogger theme, the Developer Console or automated CDP scripts might upload a newly designed theme XML successfully. The Blogger Dashboard pops up a "Theme updated successfully" toast message, but upon refreshing the live website, the changes are nowhere to be seen. You clear your cache, try incognito windows, check other devices—still, the old theme persists. We spent three agonizing days debugging this mystery, only to discover the root cause was a single comment token.

Step 1: Round-Trip Verification & Silent Reject Concept

To identify the issue, we wrote a test harness inside our Playwright environment to fetch the theme source code via Blogger's CodeMirror editor. Specifically, we called CodeMirror.getValue() to inspect the actual XML stored in the backend and compared it byte-for-byte with our uploaded local file. The comparison revealed that Blogger silently discarded parts of our XML code. Crucially, the Blogger administration UI still displayed the success notification, offering absolutely zero warnings or error codes about the rejection.

Step 2: Differential Analysis & CSS CDATA Parser Quirks

A rigorous diff between our local file and the backend-stored XML showed that the discrepancy occurred inside the <b:skin> element's CDATA section. Specifically, inside a standard CSS comment, we had left a helpful note:

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

This innocent comment broke the Blogger SkinVariables parser. While XML CDATA is technically supposed to accept any raw text, Blogger's theme compiler scans the contents of <b:skin><![CDATA[...]]></b:skin> for potential security threats. If it encounters raw HTML element tokens like <body>, <html>, or <script>—even inside CSS comments—it silently aborts the update and rejects the theme to prevent XSS vulnerability attacks.

The Fix & Prevention Lint Script

To resolve the issue, we simply swapped the raw HTML tokens in our comments with clear natural language descriptions:

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

To ensure this silent reject never disrupts our workflow again, we implemented an automated pre-flight linting script inside our deployment pipeline:

import re

DANGEROUS_TOKENS = [
    r'<html\b', r'<body\b', r'<head\b',
    r'<script\b', r'<iframe\b',
]

def lint_skin_cdata(xml: str) -> list[str]:
    skin_m = re.search(r'<b:skin>\s*<!\[CDATA\[(.*?)\]\]>\s*</b:skin>', xml, re.DOTALL)
    if not skin_m: return []
    css = skin_m.group(1)
    findings = []
    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"Dangerous token detected inside comment: {tok}")
    return findings

Since we integrated this linting safety check into our automated uploading script, our theme updates have had a 100% success rate with zero silent rejections.

ToolSignal Pro Editorial

Claude · GPT · Antigravity · Cursor 실전 오류와 해결을 5개 언어로 정리한 AI debugging archive.

이전 글 다음 글