jackwener/OpenCLI · warning · EmptyResultError

The selected players were not both present in the resolved m

Error message

The selected players were not both present in the resolved mapstats pages

What it means

buildDuelRows navigates the resolved mapstats pages and extracts a row for each selected player per map. It throws this EmptyResultError when zero map rows were produced, i.e. the two players were never both present in any of the resolved mapstats pages. This guards the summary row from being computed over an empty set.

Source

Thrown at clis/hltv/player-duel.js:289

}

async function buildDuelRows(page, args, mapUrls, scope, limit, context = {}) {
  const playerA = parsePlayerRef(args.playerA);
  const playerB = parsePlayerRef(args.playerB);
  const rows = [];

  for (const mapUrl of mapUrls.slice(0, limit)) {
    const mapRows = await readMatchMap(page, mapUrl);
    const playerARow = findPlayer(mapRows, playerA.playerId);
    const playerBRow = findPlayer(mapRows, playerB.playerId);
    if (!playerARow || !playerBRow) continue;
    const matrix = playerARow.team === playerBRow.team ? [] : await readPerformanceKillMatrix(page, mapUrl);
    const direct = parseDirectDuel(matrix, playerARow.playerName, playerBRow.playerName);
    rows.push(toMapRow(scope, mapUrl, playerARow, playerBRow, direct));
  }

  if (rows.length === 0) {
    throw new EmptyResultError('hltv player-duel', 'The selected players were not both present in the resolved mapstats pages');
  }
  return [toSummaryRow(scope, rows, context), ...rows];
}

cli({
  site: 'hltv',
  name: 'player-duel',
  description: 'Compare two HLTV players on shared maps, including direct kill matrix when available',
  access: 'read',
  example: 'opencli hltv player-duel 19230/m0nesy 3741/niko --match https://www.hltv.org/stats/matches/mapstatsid/231594/falcons-vs-natus-vincere -f json',
  domain: 'www.hltv.org',
  strategy: Strategy.UI,
  browser: true,
  navigateBefore: false,
  args: [
    { name: 'playerA', type: 'string', positional: true, required: true, help: 'First player ref: 19230/m0nesy, player URL, or stats player URL' },
    { name: 'playerB', type: 'string', positional: true, required: true, help: 'Second player ref: 3741/niko, player URL, or stats player URL' },
    { name: 'match', type: 'string', default: '', help: 'Optional HLTV match, stats series, or mapstats URL' },

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Confirm both players actually played in every resolved map (check for stand-ins)
  2. Re-resolve mapUrls so they point to mapstats pages containing both players
  3. Verify playerName strings match their HLTV display names exactly
  4. Catch EmptyResultError and surface 'players not in this match' to the user

Example fix

// before
const mapUrls = [staleMapstatsUrl];
const rows = await buildDuelRows(page, args, mapUrls, scope, limit);
// after
const mapUrls = await resolveMapStatsUrls(page, matchUrl); // fresh, includes both players
const rows = await buildDuelRows(page, args, mapUrls, scope, limit);
Defensive patterns

Strategy: validation

Validate before calling

// check both players appear on the resolved mapstats pages before building rows
const present = await page.evaluate((names) => names.every((n) => document.body.innerText.includes(n)), [playerA.playerName, playerB.playerName]);
if (!present) throw new Error('players not both present in mapstats');

Type guard

function bothPlayersExpected(mapUrls) { return Array.isArray(mapUrls) && mapUrls.length > 0; }

Try / catch

try {
  const rows = await buildDuelRows(page, args, mapUrls, scope, limit);
} catch (err) {
  if (err instanceof EmptyResultError) return []; // no shared maps in this fixture
  throw err;
}

Prevention

When it happens

Trigger: The mapUrls passed in (e.g. from a resolved match/series) contain mapstats pages where one or both player names do not appear; player name parsing fails to match table rows for every map; an empty or wrong mapUrls array is supplied.

Common situations: Passing a match URL for a game where a substitute played; lineup changed between series maps (stand-ins); stale mapstats URLs after HLTV restructures; mismatched playerName casing/special characters preventing row matching.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/611eade8946ca107. Report an issue: GitHub.