can1357/oh-my-pi · error
Failed to fetch new stories
Error message
Failed to fetch new stories
What it means
Thrown by handleHackerNews when `loadPage` returns `ok: false` for the Firebase `newstories.json` endpoint while handling https://news.ycombinator.com/newest. Same failure semantics as the top-stories variant: transport error, non-2xx status, or unreadable body after user-agent rotation.
Source
Thrown at packages/coding-agent/src/web/scrapers/hackernews.ts:162
try {
const itemId = parsed.searchParams.get("id");
if (itemId) {
const item = await fetchItem(parseInt(itemId, 10), timeout, signal);
if (!item) throw new Error(`Failed to fetch item ${itemId}`);
content = await renderStory(item, timeout, 0, signal);
notes.push(`Fetched HN item ${itemId} with top-level comments (depth 2)`);
} else if (parsed.pathname === "/" || parsed.pathname === "/news") {
const { content: raw, ok } = await loadPage(`${API_BASE}/topstories.json`, { timeout, signal });
if (!ok) throw new Error("Failed to fetch top stories");
const ids = tryParseJson<number[]>(raw);
if (!ids) throw new Error("Failed to parse top stories");
content = await renderListing(ids, timeout, "Hacker News - Top Stories", signal);
notes.push("Fetched top 20 stories from HN front page");
} else if (parsed.pathname === "/newest") {
const { content: raw, ok } = await loadPage(`${API_BASE}/newstories.json`, { timeout, signal });
if (!ok) throw new Error("Failed to fetch new stories");
const ids = tryParseJson<number[]>(raw);
if (!ids) throw new Error("Failed to parse new stories");
content = await renderListing(ids, timeout, "Hacker News - New Stories", signal);
notes.push("Fetched top 20 new stories");
} else if (parsed.pathname === "/best") {
const { content: raw, ok } = await loadPage(`${API_BASE}/beststories.json`, { timeout, signal });
if (!ok) throw new Error("Failed to fetch best stories");
const ids = tryParseJson<number[]>(raw);
if (!ids) throw new Error("Failed to parse best stories");
content = await renderListing(ids, timeout, "Hacker News - Best Stories", signal);
notes.push("Fetched top 20 best stories");
} else {
return null;
}
return buildResult(content, { url, method: "hackernews", fetchedAt, notes });
} catch (err) {
const errorMsg = err instanceof Error ? err.message : String(err);View on GitHub (pinned to 9690622007)
Solutions
- Verify connectivity: curl -I https://hacker-news.firebaseio.com/v0/newstories.json, then retry.
- Read the notes/error in the returned result block for the underlying transport error.
- Use the Algolia HN API (search_by_date with tags=story) as a fallback for newest stories.
- Increase the timeout if failures are timeouts.
- Check proxy/firewall rules for Firebase hosting domains.
Example fix
// before
const res = await webFetch("https://news.ycombinator.com/newest");
// after: pre-check upstream health and degrade
const health = await fetch("https://hacker-news.firebaseio.com/v0/newstories.json", { method: "HEAD" });
if (!health.ok) return algoliaNewestFallback();
const res = await webFetch("https://news.ycombinator.com/newest"); Defensive patterns
Strategy: retry
Validate before calling
const probe = await fetch("https://hacker-news.firebaseio.com/v0/newstories.json", { method: "HEAD" });
if (!probe.ok) throw new Error(`HN Firebase unreachable: ${probe.status}`); Try / catch
try {
const res = await webFetch("https://news.ycombinator.com/newest");
} catch (err) {
if (err instanceof ToolAbortError) throw err;
// fall back to Algolia search_by_date
} Prevention
- HEAD-probe newstories.json before fetching /newest.
- Retry once with backoff; Firebase glitches are transient.
- Verify DNS resolution of hacker-news.firebaseio.com in the environment.
- Keep an Algolia by-date fallback.
- Raise timeout on slow links instead of disabling timeouts.
When it happens
Trigger: Calling web-fetch on https://news.ycombinator.com/newest when GET https://hacker-news.firebaseio.com/v0/newstories.json fails (network outage, DNS failure, HTTP error, blocked user agents).
Common situations: Firebase API outage; offline/air-gapped environment; DNS failure; rate limiting; firewall blocking Firebase hosting; transient timeout under slow networks.
Related errors
- Failed to fetch top stories
- Failed to fetch best stories
- Failed to fetch item ${itemId}
- V2 remote compaction failed (${response.status} ${response.s
- sso-role
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/0852961160588045.
Report an issue: GitHub.