{"record":{"id":"24203e7a44a418fc","repo":"jackwener/OpenCLI","slug":"hltv-parser-returned-a-malformed-url","errorCode":null,"errorMessage":"HLTV parser returned a malformed URL","messagePattern":"HLTV parser returned a malformed URL","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/hltv/utils.js","lineNumber":106,"sourceCode":"  const raw = String(value ?? '').replace(/\\s+/g, ' ').trim();\n  if (!raw || raw === '-' || raw.toLowerCase() === 'n/a') return null;\n  const match = raw.replace(/,/g, '').match(/-?\\d+(?:\\.\\d+)?/);\n  if (!match) return null;\n  const n = Number(match[0]);\n  return Number.isFinite(n) ? n : null;\n}\n\nexport function parseMoneyUsd(value) {\n  return parseNumber(String(value ?? '').replace(/\\$/g, ''));\n}\n\nexport function absolutizeUrl(value) {\n  if (!value) return null;\n  let url;\n  try {\n    url = new URL(value, BASE);\n  } catch {\n    throw new CommandExecutionError('HLTV parser returned a malformed URL');\n  }\n  if (!isHltvHost(url.hostname)) {\n    throw new CommandExecutionError(`HLTV parser returned an off-domain URL: ${url.toString()}`);\n  }\n  return url.toString();\n}\n\nexport function extractIdFromUrl(url, kind) {\n  if (!url) return null;\n  let parsed;\n  try {\n    parsed = new URL(url, BASE);\n  } catch {\n    return null;\n  }\n  if (!isHltvHost(parsed.hostname)) return null;\n  const path = parsed.pathname;\n  const patterns = {","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hltv/utils.js#L88-L124","documentation":"absolutizeUrl resolves URLs extracted from parsed HLTV HTML against the HLTV base URL. If new URL() fails — meaning the parser produced something that is not a usable URL or path — it throws CommandExecutionError('HLTV parser returned a malformed URL'). This usually indicates the site's markup changed and the scraper captured a bad href, or an internal bug fed an invalid string.","triggerScenarios":"A parsed anchor href is empty-but-truthy garbage, contains invalid characters, or the HTML structure changed so the extractor grabs the wrong attribute content.","commonSituations":"HLTV redesigns a page and selectors start picking up malformed hrefs; caching/proxy layers injecting text into links; running an outdated CLI against an updated site.","solutions":["Update the CLI/library to the latest version (selectors may have been fixed for the new markup)","Inspect the page at the failing command's endpoint to confirm the link structure changed","Report the failing command and URL to the project so the parser can be patched","If you control the input, pass canonical /matches/... style paths or full https URLs"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function looksLikePath(u) { return typeof u === 'string' && u.length > 0 && !/[\\s<>\"']/.test(u) && /^([a-z]+:\\/\\/)?[\\w./?#&=-]+$/i.test(u); }\nif (result.url && !looksLikePath(result.url)) throw new Error('parser produced malformed URL');","typeGuard":"const isResolvableUrl = (v) => { try { new URL(v, 'https://www.hltv.org'); return true; } catch { return false; } };","tryCatchPattern":"try {\n  await hltv.match(id);\n} catch (e) {\n  if (e.name === 'CommandExecutionError' && e.message.includes('malformed URL')) {\n    console.error('Parser output unusable — update the CLI or report the page');\n  } else throw e;\n}","preventionTips":["Keep the CLI updated against HLTV markup changes","Report failing commands/pages upstream so selectors get fixed","Avoid post-processing raw HTML yourself; use the parsed fields"],"tags":["scraping","url-parsing","html-changed","hltv"],"backgroundTag":"malformed-url","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}