santifer/career-ops · error
TIMEOUT
TIMEOUT
Error message
H-1B API timeout${label} after ${timeoutMs}ms: ${url} What it means
requestJson in the h1b-sponsor plugin aborts the HTTP request after timeoutMs and throws a TIMEOUT-coded error naming the URL. The initial attempt is wrapped: an AbortError from the abort controller is converted into this timeout error (empty label), while any other error propagates unchanged. It signals the H-1B API endpoint did not respond within the configured budget.
Solutions
- Increase the request timeout (timeoutMs option/env) for large or slow queries
- Check network/proxy reachability of the API host from this machine
- Retry the request — transient slowness is common; the plugin already retries once on rate-limit responses
- Check the H-1B API status/outage before further calls
- If behind a proxy, configure proxy env vars so the request is routed correctly instead of hanging
Example fix
// before
data = await requestJson(url, { timeoutMs: 3000 });
// after
try {
data = await requestJson(url, { timeoutMs: 15000 });
} catch (e) {
if (e.code === 'TIMEOUT') data = await requestJson(url, { timeoutMs: 30000 });
else throw e;
} Defensive patterns
Strategy: retry
Validate before calling
// pre-check reachability before the real call
const ok = await fetch(BASE_URL, { method: 'HEAD', signal: AbortSignal.timeout(5000) })
.then(r => r.ok).catch(() => false);
if (!ok) throw new Error('H-1B API unreachable, skip call'); Type guard
const isApiTimeout = (e) => e?.code === 'TIMEOUT' || e?.name === 'AbortError';
Try / catch
try {
data = await requestJson(url, { timeoutMs: 15000 });
} catch (e) {
if (isApiTimeout(e)) return fallbackOrRetry(e, url);
throw e;
} Prevention
- Set realistic timeoutMs for large queries; never ship sub-5s defaults
- Wrap calls with your own exponential-backoff retry for code TIMEOUT
- Cache responses to cut repeat calls to slow endpoints
- Monitor API status and circuit-break after repeated timeouts
- Verify proxy/firewall reachability before batch runs
When it happens
Trigger: Calling any plugin API helper (e.g. fetching employer sponsorship data) where fetch does not complete within timeoutMs; the AbortController fires, attempt() rejects with AbortError, and timeoutError('') is thrown.
Common situations: Slow or rate-pressured H-1B API endpoints; offline/proxied environments where the connection hangs instead of failing fast; too-low timeoutMs for large queries; corporate firewalls silently dropping packets.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- HTTP
- torre: unexpected API response — expected
- vc-portfolios: YC API fetch failed
- All active models failed. Last error
- API error: code=
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/b1151acb68315d73.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/h1b-sponsor/lib/api.mjs:298
if (read.oversized) return { kind: 'toobig' };
try {
return { kind: 'json', body: JSON.parse(read.text) };
} catch {
return { kind: 'badjson' };
}
});
const timeoutError = (label) => {
const e = new Error(`H-1B API timeout${label} after ${timeoutMs}ms: ${url}`);
e.code = 'TIMEOUT';
return e;
};
let out;
try {
out = await attempt();
} catch (err) {
if (err && err.name === 'AbortError') throw timeoutError('');
throw err;
}
if (out.kind === 'rate') {
await sleep(Math.min(out.waitMs, MAX_RETRY_WAIT_MS));
try {
out = await attempt();
} catch (err) {
if (err && err.name === 'AbortError') throw timeoutError(' on retry');
throw err;
}
if (out.kind === 'rate') {
const e = new Error(`H-1B API rate limited: ${url}`);
e.code = 'RATE_LIMIT';
throw e;
}
}
View on GitHub (pinned to aac998c7ed)