jackwener/OpenCLI · error · TimeoutError
TimeoutError
Error message
TimeoutError
What it means
gotoAndWait() wraps page.goto (20s timeout) and page.wait (15s timeout) in a try/catch; if the underlying error message matches /timeout/i it rethrows a TimeoutError labeled with the target page and a 15-second value. It means the HLTV page did not load within the budget or the expected selector never appeared within 15 seconds.
Source
Thrown at clis/hltv/utils.js:845
rowKillsCol: parsed.left,
colKillsRow: parsed.right,
});
}
}
return entries;
});
if (!Array.isArray(matrix)) return [];
return matrix;
}
export async function gotoAndWait(page, url, selector, label) {
try {
await page.goto(url.toString(), { waitUntil: 'domcontentloaded', settleMs: 1000, timeout: 20000 });
await page.wait({ selector, timeout: 15000 });
} catch (error) {
if (/timeout/i.test(String(error?.message ?? error))) {
throw new TimeoutError(label, 15);
}
throw new CommandExecutionError(`${label} failed: ${error?.message ?? error}`);
}
}
export function assertRows(rows, command) {
if (!Array.isArray(rows)) throw new CommandExecutionError(`${command} parser returned an unexpected shape`);
if (rows.length === 0) throw new EmptyResultError(command, 'No rows were found in the visible HLTV page');
return rows;
}
export function assertRequiredFields(rows, command, fields) {
assertRows(rows, command);
for (const [index, row] of rows.entries()) {
for (const field of fields) {
if (row?.[field] === null || row?.[field] === undefined || row?.[field] === '') {
throw new CommandExecutionError(`${command} parser returned row ${index + 1} without required ${field}`);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the navigation with exponential backoff — transient slowness and guard pages usually clear
- Check general connectivity to hltv.org (curl the URL) and your proxy health
- Serialize navigations / reduce concurrency if a single browser page is reused for overlapping waits
- Increase the timeout budgets in gotoAndWait if legitimate pages are just slow
- If timeouts cluster on specific URLs, verify those pages still exist and render the expected selector
Example fix
// before
const rows = await readMatchMap(page, mapstatsUrl); // TimeoutError: hltv match map page
// after
async function withRetry(fn, attempts = 3) {
for (let i = 0; ; i++) {
try { return await fn(); }
catch (err) {
if (i + 1 >= attempts || !/timeout/i.test(String(err?.message ?? err))) throw err;
await new Promise((r) => setTimeout(r, 2000 * 2 ** i));
}
}
}
const rows = await withRetry(() => readMatchMap(page, mapstatsUrl)); Defensive patterns
Strategy: retry
Validate before calling
// preflight: confirm the page is reachable before spending the 20s+15s budgets
const res = await fetch(url, { method: 'HEAD' });
if (!res.ok) throw new Error(`page unreachable: ${res.status}`); Try / catch
try {
const rows = await readMatchMap(page, mapstatsUrl);
} catch (err) {
if (err instanceof TimeoutError) {
await new Promise((r) => setTimeout(r, 2000));
return readMatchMap(page, mapstatsUrl); // retry with backoff
}
throw err;
} Prevention
- Retry navigations with exponential backoff on TimeoutError
- Reduce concurrency per browser page; serialize gotoAndWait calls
- Monitor proxy health and HLTV availability before batch runs
- Increase the 15s/20s budgets in gotoAndWait if your network is slow
When it happens
Trigger: Calling any helper that uses gotoAndWait (e.g. readMatchMap, resolveStatsSeriesUrlFromMap) when HLTV is slow or unreachable, the anti-bot/DDoS-guard page never yields the expected selector, the URL 404s slowly, or the network/proxy is too slow for the 15s selector wait.
Common situations: Scraping under heavy rate limiting (HLTV serves interstitials that never contain '.stats-section.stats-match' or 'a[href*="/stats/matches/"]'); flaky proxies;HLTV outages or maintenance; overly aggressive parallel navigation on a single page handle.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Douyin search extraction failed: ${error instanceof Error ?
- IMDb search results did not finish loading
- Timed out waiting for network idle after ${waitSeconds}s
- weixin search failed while loading Sogou results
- 1point3acres request failed: ${error?.message || error}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/c554bf4b9dfb88a0.
Report an issue: GitHub.