can1357/oh-my-pi · error

${url}: ${res.status}

Error message

${url}: ${res.status}

What it means

getJson is the metaharness web app's fetch helper: it performs a GET and, if the response is not ok, throws an Error formatted as "<url>: <status>". It surfaces any non-2xx HTTP status (404 missing route, 500 server error, etc.) to the React load path.

Source

Thrown at packages/metaharness/src/web/app.tsx:117

	tool?: string;
	isError?: boolean;
	text?: string;
	tools?: string[];
}

// ── helpers ──────────────────────────────────────────────────────────────────

const fmtUsd = (v: number) => (v >= 100 ? `$${v.toFixed(0)}` : v >= 1 ? `$${v.toFixed(2)}` : `$${v.toFixed(3)}`);
const fmtMin = (ms: number) => `${(ms / 60000).toFixed(1)}m`;
const fmtEta = (etaMs: number | null) => {
	if (etaMs === null) return "—";
	const mins = Math.max(0, Math.round((etaMs - Date.now()) / 60000));
	return mins >= 90 ? `~${(mins / 60).toFixed(1)}h` : `~${mins}m`;
};

async function getJson<T>(url: string): Promise<T> {
	const res = await fetch(url);
	if (!res.ok) throw new Error(`${url}: ${res.status}`);
	return (await res.json()) as T;
}

function useHashRoute(): string {
	const [hash, setHash] = useState(location.hash || "#/");
	useEffect(() => {
		const onChange = () => setHash(location.hash || "#/");
		window.addEventListener("hashchange", onChange);
		return () => window.removeEventListener("hashchange", onChange);
	}, []);
	return hash;
}

/** Poll a JSON endpoint on an interval (SSE covers the run list; details poll).
 *  Returns the latest payload plus a manual refresh for after mutations. */
function usePolled<T>(url: string | null, intervalMs: number): [T | null, () => void] {
	const [data, setData] = useState<T | null>(null);
	const [nonce, setNonce] = useState(0);

View on GitHub (pinned to 9690622007)

Solutions

  1. Check the status code in the message: 404 means wrong path/server version, 5xx means server-side failure
  2. Confirm the metaharness server is running and the dashboard URL/port matches it
  3. Inspect server logs for the failing request handler
  4. Refresh the dashboard to a version matching the running server

Example fix

// before
const data = await getJson("/api/experiments/old-endpoint");
// after: handle failures gracefully in the UI
try {
  const data = await getJson("/api/experiments");
} catch (e) {
  setError(String(e));
}
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await fetch(url, { method: "HEAD" });
if (!res.ok) {
  console.warn(`API endpoint ${url} unavailable (HTTP ${res.status}); refresh the server?`);
}

Try / catch

try {
  const data = await getJson<T>(url);
} catch (err) {
  const m = /^(.+?): (\d+)$/.exec(String(err.message));
  if (m) {
    const [, u, status] = m;
    if (status === "404") showError(`Endpoint ${u} not found — server version mismatch`);
    else showError(`Request to ${u} failed (HTTP ${status})`);
    return fallbackData;
  }
  throw err;
}

Prevention

When it happens

Trigger: Any fetch in the dashboard to a URL returning a non-OK status — endpoint not mounted on the server, wrong port/hash route, API handler crashing, or auth/proxy rejection.

Common situations: Dashboard open against a stale server version whose endpoints moved; server restarted mid-session; reverse proxy returning 502; typo'd API path.

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 can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/fd47042fbf6a52ad. Report an issue: GitHub.