Hmbown/CodeWhale · error · SystemExit

error

Error message

error: {msg}

What it means

die() is the central fatal-error helper of scripts/catalog_models_dev.py: it prints 'error: <msg>' to stderr and exits with a nonzero status. Nearly every failure path in this catalog-refresh tool (bad JSON, failed HTTP fetch, malformed catalog shape, OpenRouter refresh problems) funnels through it, so the underlying cause is whatever message was passed in.

Solutions

  1. Read the msg on stderr to identify which step failed (decode, fetch, or shape validation)
  2. Re-run the refresh to rule out a transient network/API failure
  3. Inspect the fetched payload at the failing source for HTML error pages or schema changes
  4. If upstream schema drifted, update ensure_models_dev_shape to accept the new layout

Example fix

# before
raise SystemExit(1)
# after
die(f"failed to refresh catalog from {url}: HTTP {status}")
Defensive patterns

Strategy: try-catch

Validate before calling

import urllib.request
try:
    urllib.request.urlopen("https://models.dev/api.json", timeout=60)
except Exception as exc:
    print("catalog source unreachable:", exc)

Try / catch

try:
    refresh_catalog()
except SystemExit:
    # die() already printed 'error: ...' to stderr; inspect msg before retry
    raise

Prevention

When it happens

Trigger: Any call site detects a failure and calls die(msg): load_json_bytes on undecodable/invalid JSON, fetch_url on a failed download, load_models_dev_catalog or ensure_models_dev_shape on structurally wrong catalog data, cmd_refresh/refresh_openrouter on network or API errors.

Common situations: models.dev or OpenRouter returning 5xx or rate-limit responses; offline/CI network restrictions; upstream catalog schema drift breaking ensure_models_dev_shape; a truncated or HTML error page saved where JSON was expected.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/3af665d7a014938a. Report an issue: GitHub.

Appendix: source

Thrown at scripts/catalog_models_dev.py:46

import argparse
import json
import os
import sys
import urllib.error
import urllib.request
from pathlib import Path
from typing import Any

DEFAULT_MODELS_DEV_URL = "https://models.dev/catalog.json"
DEFAULT_OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models"
USER_AGENT = "CodeWhale-catalog-automation/0.9.0 (+https://github.com/Hmbown/CodeWhale)"
FETCH_TIMEOUT_SECS = 60


def die(msg: str, code: int = 1) -> None:
    print(f"error: {msg}", file=sys.stderr)
    raise SystemExit(code)


def load_json_bytes(raw: bytes, source: str) -> Any:
    try:
        text = raw.decode("utf-8")
    except UnicodeDecodeError as exc:
        die(f"{source}: not utf-8 ({exc})")
    try:
        return json.loads(text)
    except json.JSONDecodeError as exc:
        die(f"{source}: invalid JSON ({exc})")


def fetch_url(url: str) -> bytes:
    req = urllib.request.Request(
        url,
        headers={
            "User-Agent": USER_AGENT,

View on GitHub (pinned to 433685b202)