mvanhorn/last30days-skill · error · HtmlPublishError
{exc.reason}
Error message
{exc.reason} What it means
Raised by publish_html when the request fails before getting an HTTP response and the underlying exception is a urllib URLError — the message is str(exc.reason), the inner cause (DNS failure, connection refused, SSL error, timeout during connect). Chained as 'from exc' so the full traceback still shows the URLError.
Source
Thrown at skills/last30days/scripts/lib/html_publish.py:57
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
except URLError as exc:
raise HtmlPublishError(str(exc.reason)) from exc
except OSError as exc:
raise HtmlPublishError(str(exc)) from exc
try:
result = json.loads(body)
except json.JSONDecodeError as exc:
raise HtmlPublishError("publish endpoint returned non-JSON response") from exc
if not isinstance(result, dict):
raise HtmlPublishError("publish endpoint returned unexpected JSON response")
url = result.get("url")
if not isinstance(url, str) or not url.startswith("https://"):
raise HtmlPublishError("publish endpoint response did not include a valid url")
return result
def publish_html_documents(
documents: Mapping[str, str],View on GitHub (pinned to c7460f6114)
Solutions
- Verify basic connectivity: curl -I https://api.ht-ml.app/v1/sites (or your custom endpoint).
- For custom endpoints, confirm the local/remote server is up and the URL scheme/port are right.
- In proxied environments, export HTTPS_PROXY and ensure the proxy CA is trusted.
- Treat as transient only if the network is flaky; DNS/connection-refused usually means environment, not provider.
Example fix
# before
result = publish_html(html)
# after
import socket
try:
result = publish_html(html)
except HtmlPublishError as e:
if isinstance(e.__cause__, URLError) and isinstance(e.__cause__.reason, (socket.gaierror, ConnectionRefusedError)):
log.warning("endpoint unreachable: %s", e)
result = None Defensive patterns
Strategy: retry
Validate before calling
import socket
def endpoint_reachable(host: str, port: int = 443, timeout: float = 5.0) -> bool:
try:
socket.create_connection((host, port), timeout=timeout).close()
return True
except OSError:
return False Try / catch
from urllib.error import URLError
try:
publish_html(html)
except HtmlPublishError as e:
if isinstance(e.__cause__, URLError):
reason = e.__cause__.reason
# DNS failure / refused / SSL -> environment problem; fix network, do not blind-retry
log.error("publish endpoint unreachable: %s", reason) Prevention
- Check e.__cause__ to classify: gaierror (DNS), ConnectionRefusedError (server down), ssl errors (TLS/CA).
- In containers/CI, verify egress to api.ht-ml.app:443 before running publish steps.
- Set HTTPS_PROXY and trust the proxy CA in corporate networks.
When it happens
Trigger: No network / offline machine; DNS cannot resolve api.ht-ml.app (or the custom endpoint host); a firewall or proxy blocks outbound HTTPS; TLS certificate verification fails; endpoint port closed.
Common situations: Running inside a container or CI runner without network egress; corporate MITM proxy with an untrusted CA; airplane-mode laptop; a custom endpoint= pointing at a local server that is not running yet (connection refused).
Related errors
- {status}: {message}
- {exc}
- publish endpoint returned non-JSON response
- Gemini request failed: {exc}
- HTML content is empty
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/2926cc8915d20f1a.
Report an issue: GitHub.