{"record":{"id":"e0277ac8c1409fec","repo":"Hmbown/CodeWhale","slug":"invalid-base-url-args-baseurl","errorCode":null,"errorMessage":"invalid --base-url: ${args.baseUrl}","messagePattern":"invalid --base-url: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/scripts/compare-deployed-facts.mjs","lineNumber":105,"sourceCode":"      expected.latestPublishedRelease?.tag ?? null,\n      receipt.latestPublishedRelease?.tag ?? null,\n    ],\n  ];\n  for (const [field, expectedValue, deployedValue] of checks) {\n    if (expectedValue !== deployedValue) {\n      differences.push({ field, expected: expectedValue, deployed: deployedValue });\n    }\n  }\n  return differences;\n}\n\nasync function main() {\n  const args = parseArgs(process.argv.slice(2));\n  let baseUrl;\n  try {\n    baseUrl = new URL(args.baseUrl);\n  } catch {\n    throw new Error(`invalid --base-url: ${args.baseUrl}`);\n  }\n  if (!/^https?:$/.test(baseUrl.protocol)) {\n    throw new Error(\"--base-url must use http or https\");\n  }\n\n  const expectedRevision = args.expectedRevision || localRevision();\n  if (!expectedRevision || !/^[0-9a-f]{40}$/i.test(expectedRevision)) {\n    throw new Error(\"expected revision must be an exact 40-character Git SHA\");\n  }\n  if (!Number.isInteger(args.attempts) || args.attempts < 1 || args.attempts > 20) {\n    throw new Error(\"--attempts must be an integer from 1 to 20\");\n  }\n  if (!Number.isFinite(args.retryDelayMs) || args.retryDelayMs < 0 || args.retryDelayMs > 30_000) {\n    throw new Error(\"--retry-delay-ms must be between 0 and 30000\");\n  }\n\n  const facts = buildFacts();\n  const expected = {","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/web/scripts/compare-deployed-facts.mjs#L87-L123","documentation":"main() runs `new URL(args.baseUrl)` (default 'https://codewhale.net') and converts a parse failure into `invalid --base-url: ${args.baseUrl}`. URL() rejects strings without a valid scheme — 'example.com', values with stray spaces or control characters, or an empty string.","triggerScenarios":"Passing a bare host without a scheme (--base-url example.com), a value with leading/trailing whitespace or invisible characters, or an empty --base-url.","commonSituations":"Copy-pasting a domain from a browser address bar without https://; env-injected URLs carrying whitespace; a default overridden with a malformed value in CI.","solutions":["Include the scheme: `--base-url https://codewhale.net`","Trim whitespace from env-provided URLs before passing them","If the value looks correct, print it with delimiters — invisible characters fail URL() too"],"exampleFix":"# before\n--base-url example.com\n# after\n--base-url https://example.com","handlingStrategy":"validation","validationCode":"const raw = String(args.baseUrl ?? 'https://codewhale.net').trim();\nlet candidate;\ntry {\n  candidate = new URL(raw);\n} catch {\n  console.error(`invalid --base-url: ${raw} (include the scheme, e.g. https://host)`);\n  process.exit(2);\n}","typeGuard":null,"tryCatchPattern":"try {\n  baseUrl = new URL(args.baseUrl);\n} catch (error) {\n  if (error instanceof TypeError) { console.error(`invalid --base-url: ${args.baseUrl}`); process.exit(2); }\n  throw error;\n}","preventionTips":["Normalize env-provided URLs with trim() before parsing","Always paste URLs with an explicit scheme"],"tags":["cli","validation","url","web"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}