{"record":{"id":"5ae4706c0134f364","repo":"lissy93/web-check","slug":"no-target-provided","errorCode":null,"errorMessage":"No target provided","messagePattern":"No target provided","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"api/_common/parse-target.js","lineNumber":12,"sourceCode":"// Wrap bare IPv6 in brackets for URL parsing (2+ colons = IPv6)\nexport const bracketIPv6 = (str) => {\n  const bare = str.replace(/^https?:\\/\\//i, '');\n  const host = bare.split('/')[0];\n  if (!host.startsWith('[') && (host.match(/:/g) || []).length >= 2)\n    return str.replace(host, `[${host}]`);\n  return str;\n};\n\n// Normalise a user-supplied target, stripping :port for DNS lookups\nexport const parseTarget = (input) => {\n  if (!input) throw new Error('No target provided');\n  let normalised = /^https?:\\/\\//i.test(input) ? input : `https://${input}`;\n  normalised = bracketIPv6(normalised);\n  let u;\n  try {\n    u = new URL(normalised);\n  } catch {\n    throw new Error(`Invalid URL: ${input}`);\n  }\n  return {\n    hostname: u.hostname.replace(/^\\[|]$/g, ''),\n    port: u.port || null,\n    protocol: u.protocol,\n    pathname: u.pathname || '/',\n    href: u.href,\n  };\n};\n\nexport default parseTarget;","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/lissy93/web-check/blob/af1a97759fc8bcc43c876c94f2ccb018ce215f90/api/_common/parse-target.js#L1-L30","documentation":"Thrown by parseTarget in api/_common/parse-target.js when the input argument is falsy (undefined, null, empty string). This is the entry-point guard for normalising a user-supplied target before DNS resolution and URL parsing. It exists so downstream code never operates on an absent target.","triggerScenarios":"Calling parseTarget(undefined), parseTarget(null), parseTarget(''), or invoking an API endpoint backed by it without the required target query parameter.","commonSituations":"Missing ?url= (or equivalent) query parameter in the HTTP request; a caller passing a destructured variable that was never set; environment-specific configs where the param name differs between local dev and deployment.","solutions":["Supply a non-empty target string (hostname or URL) to parseTarget","Check the caller that extracts the query parameter — it is likely reading the wrong param name or from the wrong object (queryStringParameters vs query)","Add an early validation in your own handler before delegating to this API"],"exampleFix":"// before\nconst t = await parseTarget(query.target); // query.target is undefined\n\n// after\nconst raw = query.target;\nif (!raw) throw new Error('Missing \"target\" query parameter');\nconst t = await parseTarget(raw);","handlingStrategy":"validation","validationCode":"if (typeof target !== 'string' || target.trim() === '') {\n  throw new Error('Missing \"target\" query parameter');\n}\nconst parsed = parseTarget(target.trim());","typeGuard":"/** @param {unknown} v */\nconst isNonEmptyString = (v) => typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":"try {\n  const t = parseTarget(input);\n} catch (e) {\n  if (e.message === 'No target provided') return badRequest('target is required');\n  throw e;\n}","preventionTips":["Destructure query params with defaults and validate presence at the request boundary","Wire missing-param cases to 400 responses, not 500s","Keep one shared param-extraction helper so param-name drift fails loudly once"],"tags":["validation","query-parameter","api"],"backgroundTag":"missing-required-parameter","analyzedSha":"af1a97759fc8bcc43c876c94f2ccb018ce215f90","analyzedAt":"2026-08-27T11:44:27.410Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}