{"record":{"id":"3b1703ece7b93ce0","repo":"jackwener/OpenCLI","slug":"match-is-required","errorCode":null,"errorMessage":"match is required","messagePattern":"match is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/hltv/utils.js","lineNumber":462,"sourceCode":"\nexport function parseHltvDate(value) {\n  const raw = String(value ?? '').trim();\n  const shortMatch = raw.match(/^(\\d{2})\\/(\\d{2})\\/(\\d{2})$/);\n  if (shortMatch) {\n    const [, dd, mm, yy] = shortMatch;\n    return `20${yy}-${mm}-${dd}`;\n  }\n  const longMatch = raw.match(/^(\\d{2})\\/(\\d{2})\\/(\\d{4})$/);\n  if (longMatch) {\n    const [, dd, mm, yyyy] = longMatch;\n    return `${yyyy}-${mm}-${dd}`;\n  }\n  return raw;\n}\n\nexport function normalizeMatchUrl(value) {\n  const raw = String(value ?? '').trim();\n  if (!raw) throw new ArgumentError('match is required');\n  const url = /^https?:\\/\\//i.test(raw) ? parseHltvUserUrl(raw, 'match') : new URL(raw.replace(/^\\/+/, ''), `${BASE}/`);\n  if (!/^\\/(?:matches\\/\\d+\\/|stats\\/matches\\/(?:mapstatsid\\/)?\\d+\\/)/.test(url.pathname)) {\n    throw new ArgumentError('match must be an HLTV match, stats series, or mapstats URL');\n  }\n  return url;\n}\n\nfunction buildPerformanceUrl(mapstatsUrl) {\n  const url = new URL(mapstatsUrl, BASE);\n  url.pathname = url.pathname.replace('/stats/matches/mapstatsid/', '/stats/matches/performance/mapstatsid/');\n  return url;\n}\n\nexport async function resolveMatchMapUrls(page, match) {\n  const url = normalizeMatchUrl(match);\n  if (/^\\/stats\\/matches\\/mapstatsid\\/\\d+\\//.test(url.pathname)) return [url.toString()];\n\n  await gotoAndWait(page, url, 'a[href*=\"/stats/matches/mapstatsid/\"]', 'hltv match map link page');","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hltv/utils.js#L444-L480","documentation":"This ArgumentError is thrown by normalizeMatchUrl when the match value is empty after String(value ?? '').trim(). normalizeMatchUrl is the entry point that turns any HLTV match reference (match URL, stats series URL, or mapstats URL) into a normalized URL object; without a non-empty string there is nothing to normalize. It signals the caller passed an empty/whitespace value or coerced a missing value to an empty string.","triggerScenarios":"normalizeMatchUrl(''), normalizeMatchUrl(null) (explicit null with no default), normalizeMatchUrl('   '), or String() coercion of an empty value (e.g. an empty array []) reaching the function via match-lookup helpers.","commonSituations":"Env vars/CLI args like MATCH_URL='' overriding undefined; scraping pipelines where an earlier regex produced '' for a missing match link; config files with empty match fields.","solutions":["Pass a valid match reference, e.g. 'https://www.hltv.org/matches/2380210/...' or a stats mapstats URL.","Guard before calling: skip or substitute when the value is missing — if (matchValue?.trim()) normalizeMatchUrl(matchValue).","Fix the upstream source so missing matches yield null/undefined (skip) instead of '' (throw)."],"exampleFix":"// before\nnormalizeMatchUrl(config.matchUrl ?? ''); // throws when unset\n// after\nif (config.matchUrl?.trim()) {\n  normalizeMatchUrl(config.matchUrl);\n} else {\n  // skip match or use a fallback\n}","handlingStrategy":"validation","validationCode":"function hasMatchUrl(v) {\n  return typeof v === 'string' && v.trim().length > 0;\n}\nif (!hasMatchUrl(input)) throw new TypeError('match URL is required');","typeGuard":"function isMatchInput(v) {\n  return typeof v === 'string' && v.trim() !== '';\n}","tryCatchPattern":"try {\n  const url = normalizeMatchUrl(input);\n} catch (err) {\n  if (err.name === 'ArgumentError' && err.message === 'match is required') {\n    return null; // no match supplied — skip rather than crash\n  }\n  throw err;\n}","preventionTips":["Default missing match values to undefined/null and skip, not to '' which throws.","Coerce unknown sources with v == null ? null : String(v) so empties stay falsy.","Validate at the boundary (env, CLI, config) that match fields are non-empty before calling."],"tags":["argument-error","validation","hltv"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}