{"record":{"id":"95904fb33f8d8a7c","repo":"jackwener/OpenCLI","slug":"hltv-match-map-parser-found-no-player-rows","errorCode":null,"errorMessage":"hltv match-map parser found no player rows","messagePattern":"hltv match-map parser found no player rows","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/hltv/utils.js","lineNumber":602,"sourceCode":"          teamScore: currentTeam === teamOne ? teamOneScore : teamTwoScore,\n          opponent,\n          opponentScore: currentTeam === teamOne ? teamTwoScore : teamOneScore,\n          headshots: kills.paren,\n          assists: assists.main,\n          flashAssists: assists.paren,\n          tradedDeaths: deaths.paren,\n          multiKills: numberFrom(textOf(tr, '.st-mks')),\n          clutches: numberFrom(textOf(tr, '.st-clutches')),\n          roundSwingPct: numberFrom(textOf(tr, '.st-roundSwing')),\n        },\n        url: playerUrl,\n      });\n    }\n    return rows;\n  }, { base: BASE, matchStatsId });\n\n  if (!Array.isArray(rows)) throw new CommandExecutionError('hltv match-map parser returned an unexpected shape');\n  if (rows.length === 0) throw new CommandExecutionError('hltv match-map parser found no player rows');\n\n  return assertRequiredFields(rows.map((row) => ({\n    matchStatsId: row.matchStatsId,\n    playerId: row.playerId,\n    playerName: row.playerName,\n    team: row.team,\n    kills: parseNumber(row.kills),\n    deaths: parseNumber(row.deaths),\n    adr: parseNumber(row.adr),\n    kastPct: parseNumber(row.kastPct),\n    rating: parseNumber(row.rating),\n    opKd: row.opKd,\n    details: row.details,\n    url: row.url,\n  })), 'hltv match-map', ['matchStatsId', 'playerId', 'playerName', 'team', 'url']);\n}\n\nfunction round(value, digits = 2) {","sourceCodeStart":584,"sourceCodeEnd":620,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hltv/utils.js#L584-L620","documentation":"The map-stats page loaded and page.evaluate returned an array, but zero player rows were extracted from '.stats-table.totalstats tr'. readMatchMap treats an empty table as an error (CommandExecutionError) because a valid map stats page always lists the players of both teams.","triggerScenarios":"Navigating to a mapstatsid page whose stats table has not rendered (page still loading beyond the wait selector), a completed-but-empty/forfeited map, HLTV layout changes renaming .stats-table.totalstats or .st-teamname/player link selectors, or being served an anti-bot/redirect page that still contains the waited selector.","commonSituations":"HLTV markup changes after a site redesign; scraping very old maps with a different table layout; rate-limited sessions receiving simplified pages; map pages for matches that were forfeited or where stats were never recorded.","solutions":["Retry the request after a short delay — the table may render later than the waited selector","Check HLTV in a browser for the specific mapstatsid to confirm the table exists; skip maps without recorded stats","Inspect the loaded HTML; if selectors changed, update or upgrade the library's parser","Reduce scraping rate / change IP if guard pages are suspected"],"exampleFix":"// before\nconst rows = await readMatchMap(page, mapstatsUrl); // throws when table is empty\n// after\nlet rows;\ntry {\n  rows = await readMatchMap(page, mapstatsUrl);\n} catch (err) {\n  if (/found no player rows/.test(err.message)) {\n    await sleep(3000);\n    rows = await readMatchMap(page, mapstatsUrl);\n  } else throw err;\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const rows = await readMatchMap(page, mapstatsUrl);\n} catch (err) {\n  if (/found no player rows/.test(String(err?.message))) {\n    await new Promise((r) => setTimeout(r, 3000));\n    return readMatchMap(page, mapstatsUrl); // second failure => treat as data-less map\n  }\n  throw err;\n}","preventionTips":["Retry once before giving up — table may render late","Skip mapstatsid pages known to have no recorded stats (forfeits)","Keep the library updated for HLTV markup changes affecting .stats-table.totalstats","Rate-limit requests so guard pages with empty tables are not served"],"tags":["hltv","scraping","empty-result","selector"],"backgroundTag":"empty-scrape-result","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}