decolua/9router · warning · Error

`HTTP ${res.status}`

Error message

`HTTP ${res.status}`

What it means

ChangelogModal fetches markdown from GITHUB_CONFIG.changelogUrl and throws `HTTP ${res.status}` whenever the response is not ok (non-2xx). The thrown message is caught in the same effect and shown as the modal's error text. It is a thin HTTP-status passthrough, so the message is literally like 'HTTP 404' or 'HTTP 403'.

Source

Thrown at src/shared/components/ChangelogModal.js:23

import PropTypes from "prop-types";
import { marked } from "marked";
import { GITHUB_CONFIG } from "@/shared/constants/config";

marked.setOptions({ gfm: true, breaks: true });

export default function ChangelogModal({ isOpen, onClose }) {
  const [html, setHtml] = useState("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const modalRef = useRef(null);

  useEffect(() => {
    if (!isOpen || html) return;
    setLoading(true);
    setError("");
    fetch(GITHUB_CONFIG.changelogUrl)
      .then((res) => {
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        return res.text();
      })
      .then((md) => setHtml(marked.parse(md)))
      .catch((err) => setError(err.message || "Failed to load"))
      .finally(() => setLoading(false));
  }, [isOpen, html]);

  useEffect(() => {
    const handleClickOutside = (e) => {
      if (modalRef.current && !modalRef.current.contains(e.target)) {
        onClose();
      }
    };
    if (isOpen) {
      document.addEventListener("mousedown", handleClickOutside);
      return () => document.removeEventListener("mousedown", handleClickOutside);
    }
  }, [isOpen, onClose]);

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Check GITHUB_CONFIG.changelogUrl points to an existing file (open it in a browser); fix owner/repo/branch/path if it 404s
  2. If 403, wait out the GitHub rate limit or use an authenticated/raw URL with caching
  3. Verify network access to the host (curl the URL); configure proxy if blocked
  4. Render a fallback: link the user to the changelog page on GitHub when fetch fails

Example fix

// before
if (!res.ok) throw new Error(`HTTP ${res.status}`);
// after
if (!res.ok) throw new Error(`Changelog load failed (HTTP ${res.status}). Check ${GITHUB_CONFIG.changelogUrl}`);
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await fetch(GITHUB_CONFIG.changelogUrl, { method: "HEAD" });
if (!res.ok) console.warn("Changelog unavailable:", res.status);

Type guard

function isOk(res) { return res && typeof res.ok === "boolean" && res.ok; }

Try / catch

try {
  const res = await fetch(GITHUB_CONFIG.changelogUrl);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  setHtml(marked.parse(await res.text()));
} catch (err) {
  setError(err.message || "Failed to load");
  // show fallback link to the changelog on GitHub
}

Prevention

When it happens

Trigger: fetch(GITHUB_CONFIG.changelogUrl) resolving with res.ok === false — e.g. 404 when CHANGELOG.md does not exist at that path/branch in the repo, 403 from GitHub rate limiting, 5xx from GitHub, or a network-level redirect to an error page.

Common situations: Repo renamed/branch renamed so the raw changelog URL 404s; GitHub API/raw rate limit (403) after many requests; offline or corporate proxy blocking raw.githubusercontent.com; misconfigured GITHUB_CONFIG owner/repo values.

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 decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/32e2fa9072543a14. Report an issue: GitHub.