santifer/career-ops · error · Error
vc-portfolios: YC API fetch failed
Error message
vc-portfolios: YC API fetch failed — ${err.message} What it means
fetchYCCompanies paginates the YC companies API (api.ycombinator.com/v0.1/companies). If the very first page (page === 1) fetch fails — whether from fetchWithTimeout throwing an HTTP error or res.json() failing to parse — the function aborts with 'vc-portfolios: YC API fetch failed — <cause>'. Failures on pages after the first are tolerated and return partial data, so this error specifically means the seed builder could not retrieve ANY YC data.
Solutions
- Check the inner err.message for the root cause (HTTP status vs JSON parse error) and test the URL directly with curl
- Wait and retry if rate-limited (429) or if the YC API is having an incident
- Verify network access from the environment running the seed script (CI containers often lack egress)
- If the v0.1 API is deprecated, update the script to the current YC API version or a YC company dataset export
Example fix
// before
node seeds/vc-portfolios.mjs
// Error: vc-portfolios: YC API fetch failed — HTTP 429: Too Many Requests
// after: add retry/backoff around the first page
curl -s -o /dev/null -w '%{http_code}' 'https://api.ycombinator.com/v0.1/companies?page=1&per_page=1000'
// if 429, wait (e.g. sleep 60) or reduce request frequency, then rerun Defensive patterns
Strategy: retry
Validate before calling
const reachable = await fetch('https://api.ycombinator.com/v0.1/companies?page=1&per_page=1')
.then(r => r.ok).catch(() => false);
if (!reachable) { /* abort or defer the YC seed step */ } Try / catch
try {
const companies = await fetchYCCompanies({ timeoutMs });
} catch (err) {
console.error(`YC seed unavailable: ${err.message}`);
// retry later or continue with other seed sources
} Prevention
- Add exponential backoff on the first-page fetch before failing
- Cache the last successful YC payload and fall back to it on total failure
- Schedule seed runs off-peak to avoid rate limits
- Alert on this error in CI so an API deprecation is noticed quickly
When it happens
Trigger: Calling fetchYCCompanies when page 1 of https://api.ycombinator.com/v0.1/companies returns a non-2xx status (rate limited, API down) or returns a body that is not valid JSON (HTML error page, empty body), causing fetchWithTimeout or res.json() to throw.
Common situations: YC API outage or deprecation of the v0.1 endpoint; rate limiting after repeated seed runs; a captive portal / proxy returning an HTML page so res.json() throws SyntaxError; DNS/network failure in a CI job without internet access.
Related errors
- API error: code=
- HTTP
- jobbankca: all keyword request(s) failed
- TIMEOUT
- torre: unexpected API response — expected
AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01).
Data as JSON: /api/errors/f757874a6eff9c0c.
Report an issue: GitHub.
Appendix: 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 1696bec4d0)