{"record":{"id":"ceb3351963711e8c","repo":"responsively-org/responsively-app","slug":"not-a-valid-url","errorCode":null,"errorMessage":"Not a valid URL","messagePattern":"Not a valid URL","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"desktop-app/src/main/util.ts","lineNumber":38,"sourceCode":"export function isValidCliArgURL(arg?: string): boolean {\n  if (isCliArgResult !== undefined) {\n    return isCliArgResult;\n  }\n  if (arg == null || arg === '') {\n    isCliArgResult = false;\n    return false;\n  }\n  try {\n    const url = new URL(arg);\n    if (url.protocol === 'http:' || url.protocol === 'https:' || url.protocol === 'file:') {\n      isCliArgResult = true;\n      return true;\n    }\n    // eslint-disable-next-line no-console\n    console.warn('Protocol not supported', url.protocol);\n  } catch (e) {\n    // eslint-disable-next-line no-console\n    console.warn('Not a valid URL', arg, e);\n  }\n  isCliArgResult = false;\n  return false;\n}\n\nexport const getPackageJson = () => {\n  let appPath;\n  if (process.env.NODE_ENV === 'production') appPath = app.getAppPath();\n  else appPath = process.cwd();\n\n  const pkgPath = path.join(appPath, 'package.json');\n  if (fs.existsSync(pkgPath)) {\n    const pkgContent = fs.readFileSync(pkgPath, 'utf-8');\n    return JSON.parse(pkgContent);\n  }\n  console.error(`cant find package.json in: '${appPath}'`);\n  return {};\n};","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/responsively-org/responsively-app/blob/e5623c5a70c0c476b3f247c8d3980c7224e36410/desktop-app/src/main/util.ts#L20-L56","documentation":"This console.warn fires in the catch block of isValidCliArgURL when new URL(arg) itself throws a SyntaxError, meaning the CLI argument is not a parseable URL at all (not merely an unsupported protocol). The raw argument and the underlying error are logged, the cached isCliArgResult is set to false, and the function returns false so the caller treats the argument as invalid.","triggerScenarios":"Passing a bare string like 'example.com' (no scheme), an empty string, a string with spaces/invalid characters, or malformed input like 'http://' or 'ht!tp://x' as a CLI argument.","commonSituations":"Users forgetting the https:// prefix, shell scripts passing unquoted values that get mangled, empty args from environment expansion, Windows paths like C:\\file.txt (backslashes are invalid in URLs).","solutions":["Prefix the argument with a scheme before passing it, e.g. https://example.com instead of example.com","On the code side, auto-prepend https:// when the arg looks like a bare domain before new URL()","Quote arguments in shell scripts so spaces and special characters survive","Convert Windows file paths to file:/// URLs (forward slashes) before passing"],"exampleFix":"// before\napp --open example.com/page\n// after\napp --open https://example.com/page\n// code-side normalization\nif (!/^[a-z][a-z0-9+.-]*:/i.test(arg)) arg = 'https://' + arg;","handlingStrategy":"validation","validationCode":"function looksLikeBareDomain(s: string): boolean {\n  return /^[\\w-]+(\\.[\\w-]+)+([/?#].*)?$/.test(s);\n}\nconst normalized = /^[a-z][a-z0-9+.-]*:/i.test(arg) ? arg : 'https://' + arg;\nlet ok = false;\ntry { new URL(normalized); ok = true; } catch { ok = false; }","typeGuard":"function isParseableUrl(s: string): s is string {\n  try { new URL(s); return true; } catch { return false; }\n}","tryCatchPattern":null,"preventionTips":["Require a scheme in user-facing docs and flag bare domains in input validation","Auto-prepend https:// for arguments matching a domain pattern before new URL()","Quote CLI arguments in shell scripts to prevent mangling","Reject empty and whitespace-only args before parsing"],"tags":["url-validation","cli","syntax-error","user-input"],"backgroundTag":"malformed-url-input","analyzedSha":"e5623c5a70c0c476b3f247c8d3980c7224e36410","analyzedAt":"2026-08-31T10:58:12.271Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}