santifer/career-ops · error · Error
vc-portfolios: a16z portfolio fetch failed
Error message
vc-portfolios: a16z portfolio fetch failed — ${err.message} What it means
fetchA16zCompanies downloads the a16z portfolio HTML page via fetchWithTimeout and re-throws any fetch failure as 'vc-portfolios: a16z portfolio fetch failed — <cause>'. Unlike the YC fetcher, there is no partial-data fallback: any network or HTTP error is fatal for this source. Parsing failures (parseA16zPayload) are NOT caught here — only the fetch itself.
Solutions
- Test A16Z_PORTFOLIO_URL with curl -I to see the actual status; if 403/Cloudflare, the endpoint needs a browser-like User-Agent or a headless-browser fetch
- Verify the portfolio page still exists after a site redesign and update A16Z_PORTFOLIO_URL to the new URL
- Increase timeoutMs if the failure is a timeout on a slow connection
- Check the inner err.message — timeouts, DNS failures (ENOTFOUND) and HTTP statuses each need different fixes (network/VPN vs URL update vs backoff)
Example fix
// before
const res = await fetchWithTimeout(A16Z_PORTFOLIO_URL, { timeoutMs });
// Error: vc-portfolios: a16z portfolio fetch failed — HTTP 403: ...Just a moment...
// after: allow configuring a browser-like UA / longer timeout
const res = await fetchWithTimeout(A16Z_PORTFOLIO_URL, { timeoutMs: 30000, headers: { 'user-agent': 'Mozilla/5.0 (compatible; seed-fetcher)' } }); Defensive patterns
Strategy: fallback
Validate before calling
const status = await fetch(A16Z_PORTFOLIO_URL, { method: 'HEAD' })
.then(r => r.status).catch(() => 0);
if (status !== 200) console.warn(`a16z portfolio URL unhealthy (HTTP ${status}) — expect fetch failure`); Try / catch
let companies;
try {
companies = await fetchA16zCompanies({ timeoutMs });
} catch (err) {
console.warn(`${err.message}; using cached a16z portfolio`);
companies = loadCachedA16z() ?? [];
} Prevention
- Keep a cached copy of the last successful portfolio parse for fallback
- Re-verify A16Z_PORTFOLIO_URL after any site redesign; treat 403 as bot-protection and use a browser-like UA or headless browser
- Set timeoutMs generously for large pages
- Skip the a16z source gracefully instead of failing the whole seed run
When it happens
Trigger: Calling fetchA16zCompanies when https://a16z.com/portfolio (A16Z_PORTFOLIO_URL) returns a non-2xx status via fetchWithTimeout (403 from bot protection, 404 after a site redesign, 5xx outage), or the request times out / DNS fails.
Common situations: a16z.com serving a Cloudflare challenge page to non-browser clients (403); the portfolio URL changed when a16z redesigned their site; corporate firewall blocks the domain; timeout hit because the page is large and the connection is slow.
Related errors
- could not download the index
- Could not fetch job page
- could not read the release pointer
- csod: no anonymous token on
- HTTP
AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01).
Data as JSON: /api/errors/48361f7727fd0b05.
Report an issue: GitHub.
Appendix: source
Thrown at seeds/vc-portfolios.mjs:419
return null;
}
/**
* Fetch the a16z public portfolio page and return parsed SeedCompany entries.
*
* a16z does not expose a public JSON API, so we fetch the HTML portfolio page
* and parse it with `parseA16zPayload()`.
*
* @param {{ timeoutMs?: number }} [opts]
* @returns {Promise<SeedCompany[]>}
*/
export async function fetchA16zCompanies({ timeoutMs = DEFAULT_TIMEOUT_MS } = {}) {
let html;
try {
const res = await fetchWithTimeout(A16Z_PORTFOLIO_URL, { timeoutMs });
html = await res.text();
} catch (err) {
throw new Error(`vc-portfolios: a16z portfolio fetch failed — ${err.message}`);
}
return parseA16zPayload(html);
}
// ── SEED_SOURCES registry ────────────────────────────────────────────
/**
* Registry mapping seed source names to their fetch functions.
* Consumed by scan-ats-full.mjs --seeds flag and CLI tooling.
*
* To add a new VC portfolio:
* 1. Add a fetchXyzCompanies() function above.
* 2. Add an entry here: { fetch: fetchXyzCompanies, label: 'XYZ Portfolio' }
*
* @type {Record<string, { fetch: (opts?: object) => Promise<SeedCompany[]>, label: string }>}
*/
export const SEED_SOURCES = {
yc: {View on GitHub (pinned to 1696bec4d0)