{"record":{"id":"b159a8f5c935ca21","repo":"jackwener/OpenCLI","slug":"player-is-required","errorCode":null,"errorMessage":"player is required","messagePattern":"player is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/hltv/utils.js","lineNumber":178,"sourceCode":"\n  let path = raw;\n  if (/^https?:\\/\\//i.test(raw)) path = parseHltvUserUrl(raw, 'team').pathname;\n  path = path.replace(/^https?:\\/\\/[^/]+/i, '').replace(/^\\/+/, '');\n\n  const statsMatch = path.match(/^stats\\/teams(?:\\/matches)?\\/(\\d+)\\/([a-z0-9-]+)/i);\n  const teamMatch = path.match(/^team\\/(\\d+)\\/([a-z0-9-]+)/i);\n  const compactMatch = path.match(/^(\\d+)\\/([a-z0-9-]+)$/i);\n  const match = statsMatch || teamMatch || compactMatch;\n  if (!match) {\n    throw new ArgumentError('team must be like 6667/falcons, a team URL, or a stats team URL');\n  }\n\n  return { teamId: match[1], slug: match[2].toLowerCase() };\n}\n\nexport function parsePlayerRef(value, defaultValue = '3741/niko') {\n  const raw = String(value ?? defaultValue).trim();\n  if (!raw) throw new ArgumentError('player is required');\n\n  let path = raw;\n  if (/^https?:\\/\\//i.test(raw)) path = parseHltvUserUrl(raw, 'player').pathname;\n  path = path.replace(/^https?:\\/\\/[^/]+/i, '').replace(/^\\/+/, '');\n\n  const statsMatch = path.match(/^stats\\/players(?:\\/matches)?\\/(\\d+)\\/([a-z0-9-]+)/i);\n  const playerMatch = path.match(/^player\\/(\\d+)\\/([a-z0-9-]+)/i);\n  const compactMatch = path.match(/^(\\d+)\\/([a-z0-9-]+)$/i);\n  const match = statsMatch || playerMatch || compactMatch;\n  if (!match) {\n    throw new ArgumentError('player must be like 3741/niko, a player URL, or a stats player URL');\n  }\n\n  return { playerId: match[1], slug: match[2].toLowerCase() };\n}\n\nfunction formatDate(date) {\n  const yyyy = date.getUTCFullYear();","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hltv/utils.js#L160-L196","documentation":"This ArgumentError is thrown by parsePlayerRef in clis/hltv/utils.js when the player reference argument is empty. parsePlayerRef normalizes String(value ?? defaultValue).trim(); if the resulting string is empty — even though a default of '3741/niko' exists — the function refuses to proceed because it cannot build a valid HLTV player identity ({playerId, slug}). It indicates a programming/config mistake: an empty string or whitespace-only value was passed explicitly.","triggerScenarios":"Calling playerA(''), playerB('   '), or passing { player: '' } into { playerId, slug } — any explicit empty or whitespace-only string. Note that null/undefined fall back to the default, so this fires only when a non-nullish empty value is supplied (or when String() coercion of a value yields an empty string, e.g. an empty array []).","commonSituations":"Config/env vars like PLAYER_REF='' read as empty strings instead of undefined; shell scripts passing \"$VAR\" with unset vars; form/CLI inputs not trimmed and defaulted; JSON config with empty fields overriding the built-in default.","solutions":["Remove the empty argument so null/undefined falls back to the default '3741/niko', or pass a valid ref like '3741/niko'.","Check where the value originates (env var, CLI arg, config) and default it to null/undefined instead of '' before calling.","Trim and validate the input before calling: if (!input?.trim()) skip or substitute a real player ref."],"exampleFix":"// before\nbuildPlayerUrl(process.env.PLAYER ?? ''); // throws if PLAYER=''\n// after\nconst ref = process.env.PLAYER?.trim() ? process.env.PLAYER : undefined;\nbuildPlayerUrl(ref); // falls back to default '3741/niko'","handlingStrategy":"validation","validationCode":"function isValidPlayerRef(v) {\n  return typeof v === 'string' && v.trim().length > 0;\n}\nif (!isValidPlayerRef(input)) throw new TypeError('player must be a non-empty string');","typeGuard":"function hasPlayerRef(v) {\n  return typeof v === 'string' && v.trim() !== '';\n}","tryCatchPattern":"try {\n  const { playerId, slug } = parsePlayerRef(input);\n} catch (err) {\n  if (err.name === 'ArgumentError' && err.message === 'player is required') {\n    // fall back to default player\n  } else throw err;\n}","preventionTips":["Never pass '' explicitly — pass undefined/null to get the default '3741/niko'.","Trim env/CLI inputs before use and convert empty strings to undefined at the boundary.","Coerce with ?? undefined rather than ?? '' when defaulting."],"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"}