{"record":{"id":"723574956d8766ec","repo":"neoclide/coc.nvim","slug":"not-valid-protocol-with-urlinput-should-be-htt","errorCode":null,"errorMessage":"Not valid protocol with ${urlInput}, should be http: or https:","messagePattern":"Not valid protocol with (.+?), should be http: or https:","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/model/fetch.ts","lineNumber":77,"sourceCode":"   */\n  password?: string\n  /** Maximum decompressed response size in bytes. Defaults to 128 MiB. */\n  maxResponseSize?: number\n}\n\nexport function getRequestModule(url: URL): typeof http | typeof https {\n  return url.protocol === 'https:' ? https : http\n}\n\nexport function getText(data: any): string | Buffer {\n  if (typeof data === 'string' || Buffer.isBuffer(data)) return data\n  return JSON.stringify(data)\n}\n\nexport function toURL(urlInput: string | URL): URL {\n  if (urlInput instanceof URL) return urlInput\n  let url = new URL(urlInput)\n  if (!['https:', 'http:'].includes(url.protocol)) throw new Error(`Not valid protocol with ${urlInput}, should be http: or https:`)\n  return url\n}\n\nexport function toPort(port: number | string | undefined, protocol: string): number {\n  if (port) {\n    port = typeof port === 'number' ? port : parseInt(port, 10)\n    if (!isNaN(port)) return port\n  }\n  return protocol.startsWith('https') ? 443 : 80\n}\n\nexport function getDataType(data: any): string {\n  if (data === null) return 'null'\n  if (data === undefined) return 'undefined'\n  if (typeof data == 'string') return 'string'\n  if (Buffer.isBuffer(data)) return 'buffer'\n  if (Array.isArray(data) || objectLiteral(data)) return 'object'\n  return 'unknown'","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/neoclide/coc.nvim/blob/50e974d9692461a69147d5cab146a8d3e439abe4/src/model/fetch.ts#L59-L95","documentation":"toURL in src/model/fetch.ts parses the input into a URL object and then enforces that the protocol is http: or https:, since the request layer only supports those HTTP-based schemes. Any other scheme (file:, ftp:, ws:, data:) throws 'Not valid protocol with <input>, should be http: or https:'. Note that an unparseable URL string throws a native 'Invalid URL' error from the URL constructor before this check.","triggerScenarios":"Calling fetch()/toURL() with 'ftp://example.com/file', 'file:///path', 'ws://...', or an https URL string containing an unexpected scheme typed by the user; config values like language server download URLs pointing at non-HTTP mirrors.","commonSituations":"Mirrors configured with ftp:// URLs; reusing WebSocket URLs in an HTTP fetch call; local file paths passed where an HTTP URL is expected.","solutions":["Use an http:// or https:// URL for the resource.","For local files, read them with fs instead of the fetch API.","Validate the scheme before calling: new URL(input).protocol is 'http:' or 'https:'."],"exampleFix":"// before\nawait fetch('ftp://mirror.example.com/tool.tgz')\n// after\nawait fetch('https://mirror.example.com/tool.tgz')","handlingStrategy":"validation","validationCode":"function isHttpUrl(input) {\n  try { return ['http:', 'https:'].includes(new URL(input).protocol) } catch { return false }\n}\nif (!isHttpUrl(urlInput)) throw new Error(`URL must be http(s): ${urlInput}`)","typeGuard":"function isHttpUrl(u: unknown): u is string {\n  if (typeof u !== 'string') return false\n  try { return ['http:', 'https:'].includes(new URL(u).protocol) } catch { return false }\n}","tryCatchPattern":"try {\n  return await fetch(urlInput)\n} catch (e) {\n  if (/Not valid protocol/.test(e.message)) throw new Error(`Only http(s) URLs are supported, got: ${urlInput}`)\n  throw e\n}","preventionTips":["Sanitize configured URLs to start with https:// (or http:// for local mirrors).","Use fs.readFile for local files instead of routing file:// through fetch.","Validate scheme when accepting URLs from user config or LLM-generated input."],"tags":["network","url","validation","protocol"],"backgroundTag":"unsupported-url-protocol","analyzedSha":"50e974d9692461a69147d5cab146a8d3e439abe4","analyzedAt":"2026-08-31T11:17:23.966Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}