santifer/career-ops · error · Error

vc-portfolios: YC API fetch failed — ${err.message}

Error message

vc-portfolios: YC API fetch failed — ${err.message}

What it means

fetchYCCompanies() walks the YC API page by page. If the very first page (page=1) fetch fails — wrapping the underlying fetchWithTimeout error — it throws an Error, because no data at all could be obtained. Failures on subsequent pages (page > 1) are tolerated as partial data (the loop breaks). This balances robustness (partial progress is useful) with fail-fast on total inability to reach the source.

Source

Thrown at seeds/vc-portfolios.mjs:347

 */
export async function fetchYCCompanies({ timeoutMs = DEFAULT_TIMEOUT_MS, maxPages = YC_MAX_PAGES } = {}) {
  /** @type {SeedCompany[]} */
  const all = [];
  const seen = new Set();

  // YC_MAX_PAGES is a hard ceiling: clamp here so an explicit maxPages (or a
  // stray Infinity) can never spin the walk past the runaway guard.
  const limit = Math.min(maxPages, YC_MAX_PAGES);

  let page = 1;
  for (let fetched = 0; fetched < limit; fetched++) {
    const url = `https://api.ycombinator.com/v0.1/companies?page=${page}&per_page=1000`;
    let payload;
    try {
      const res = await fetchWithTimeout(url, { timeoutMs });
      payload = await res.json();
    } catch (err) {
      if (page === 1) throw new Error(`vc-portfolios: YC API fetch failed — ${err.message}`);
      break; // Partial data is fine after page 1.
    }

    const entries = parseYCPayload(payload);
    if (entries.length === 0) break; // No more companies.

    for (const e of entries) {
      if (!seen.has(e.slug)) {
        seen.add(e.slug);
        all.push(e);
      }
    }

    // The API caps page size server-side (~30/page; per_page is ignored) and
    // reports totalPages — follow its signal instead of guessing from batch size.
    const raw = /** @type {any} */ (payload);
    if (Number.isInteger(raw?.totalPages) && raw.totalPages > 0) {
      if (page >= raw.totalPages) break;

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Verify connectivity: curl -I https://api.ycombinator.com/v0.1/companies?page=1&per_page=1000.
  2. Increase the timeout: pass a larger timeoutMs to fetchYCCompanies (default DEFAULT_TIMEOUT_MS).
  3. Retry the scan later if the YC API is having a transient outage.
  4. If behind a proxy, ensure HTTPS_PROXY / fetch agent is configured.
Defensive patterns

Strategy: retry

Try / catch

try {
  companies = await fetchYCCompanies({ timeoutMs });
} catch (err) {
  if (err.message.includes('YC API fetch failed')) {
    console.error(`YC seed unavailable: ${err.message}. Continuing without YC.`);
    companies = [];
  } else throw err;
}

Prevention

When it happens

Trigger: The YC API (api.ycombinator.com) is unreachable, returns non-2xx on the first page, or the abort timeout fires before the first response completes. Network outage, DNS failure, or a blocking firewall on page 1.

Common situations: Offline or behind a corporate firewall blocking api.ycombinator.com; a transient outage during a seed scan; a too-aggressive timeoutMs that aborts the large first page (per_page=1000).

Related errors


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/f757874a6eff9c0c. Report an issue: GitHub.