mvanhorn/last30days-skill · error · HtmlPublishError

HTML content is empty

Error message

HTML content is empty

What it means

Raised by publish_html in html_publish.py when html_content is empty or contains only whitespace. The hosted publish endpoint (default https://api.ht-ml.app/v1/sites) would reject an empty document anyway, so the client fails fast before any network I/O. It is an HtmlPublishError (subclass of RuntimeError), the single exception type for the whole publish flow.

Source

Thrown at skills/last30days/scripts/lib/html_publish.py:37

class HtmlPublishBatchResult(dict[str, dict[str, Any]]):
    """Successful document publishes plus an optional later failure."""

    def __init__(self) -> None:
        super().__init__()
        self.error: HtmlPublishError | None = None


def publish_html(
    html_content: str,
    *,
    password: str | None = None,
    endpoint: str = DEFAULT_ENDPOINT,
    opener: Callable[..., Any] | None = None,
    timeout: int = 30,
) -> dict[str, Any]:
    """Publish a single HTML document and return the provider response."""
    if not html_content.strip():
        raise HtmlPublishError("HTML content is empty")

    payload: dict[str, str] = {"html_content": html_content}
    if password is not None:
        payload["password"] = password

    request = Request(
        endpoint,
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json", "Accept": "application/json"},
        method="POST",
    )
    open_fn = opener or urlopen
    try:
        with open_fn(request, timeout=timeout) as response:
            body = response.read().decode("utf-8")
    except HTTPError as exc:
        detail = exc.read().decode("utf-8", errors="replace")
        raise HtmlPublishError(_error_message(exc.code, detail)) from exc

View on GitHub (pinned to c7460f6114)

Solutions

  1. Check the render output before publishing: if the renderer returned empty, fix the renderer/data rather than the publish call.
  2. Guard the call site: skip publish when content is blank and surface a clearer upstream error.
  3. If empty documents are legitimately possible, branch to a fallback page or abort the batch with a specific message.

Example fix

# before
publish_html(rendered)  # rendered == ""

# after
if not rendered.strip():
    raise RuntimeError("renderer produced empty HTML for this topic")
publish_html(rendered)
Defensive patterns

Strategy: validation

Validate before calling

def is_publishable(html: str) -> bool:
    return isinstance(html, str) and bool(html.strip())

Type guard

def is_nonempty_html(content: object) -> bool:
    return isinstance(content, str) and len(content.strip()) > 0

Try / catch

try:
    publish_html(html)
except HtmlPublishError as e:
    if str(e) == "HTML content is empty":
        # fix the upstream renderer; do not retry the publish
        ...

Prevention

When it happens

Trigger: Calling publish_html("") or publish_html(" \n"); passing a rendered string from a template that produced nothing (empty topic data, renderer bug); passing a variable that was never assigned because an upstream render step failed silently.

Common situations: A publish step wired into a pipeline where the render stage returned an empty string on failure instead of raising; conditional content that is all-falsy for a given dataset; trailing refactor that renamed the render output variable.

Related errors


AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15). Data as JSON: /api/errors/34169fb48f395fbe. Report an issue: GitHub.