neoclide/coc.nvim · error

Not valid protocol with ${urlInput}, should be http: or http

Error message

Not valid protocol with ${urlInput}, should be http: or https:

What it means

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.

Source

Thrown at src/model/fetch.ts:77

   */
  password?: string
  /** Maximum decompressed response size in bytes. Defaults to 128 MiB. */
  maxResponseSize?: number
}

export function getRequestModule(url: URL): typeof http | typeof https {
  return url.protocol === 'https:' ? https : http
}

export function getText(data: any): string | Buffer {
  if (typeof data === 'string' || Buffer.isBuffer(data)) return data
  return JSON.stringify(data)
}

export function toURL(urlInput: string | URL): URL {
  if (urlInput instanceof URL) return urlInput
  let url = new URL(urlInput)
  if (!['https:', 'http:'].includes(url.protocol)) throw new Error(`Not valid protocol with ${urlInput}, should be http: or https:`)
  return url
}

export function toPort(port: number | string | undefined, protocol: string): number {
  if (port) {
    port = typeof port === 'number' ? port : parseInt(port, 10)
    if (!isNaN(port)) return port
  }
  return protocol.startsWith('https') ? 443 : 80
}

export function getDataType(data: any): string {
  if (data === null) return 'null'
  if (data === undefined) return 'undefined'
  if (typeof data == 'string') return 'string'
  if (Buffer.isBuffer(data)) return 'buffer'
  if (Array.isArray(data) || objectLiteral(data)) return 'object'
  return 'unknown'

View on GitHub (pinned to 50e974d969)

Solutions

  1. Use an http:// or https:// URL for the resource.
  2. For local files, read them with fs instead of the fetch API.
  3. Validate the scheme before calling: new URL(input).protocol is 'http:' or 'https:'.

Example fix

// before
await fetch('ftp://mirror.example.com/tool.tgz')
// after
await fetch('https://mirror.example.com/tool.tgz')
Defensive patterns

Strategy: validation

Validate before calling

function isHttpUrl(input) {
  try { return ['http:', 'https:'].includes(new URL(input).protocol) } catch { return false }
}
if (!isHttpUrl(urlInput)) throw new Error(`URL must be http(s): ${urlInput}`)

Type guard

function isHttpUrl(u: unknown): u is string {
  if (typeof u !== 'string') return false
  try { return ['http:', 'https:'].includes(new URL(u).protocol) } catch { return false }
}

Try / catch

try {
  return await fetch(urlInput)
} catch (e) {
  if (/Not valid protocol/.test(e.message)) throw new Error(`Only http(s) URLs are supported, got: ${urlInput}`)
  throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: Mirrors configured with ftp:// URLs; reusing WebSocket URLs in an HTTP fetch call; local file paths passed where an HTTP URL is expected.

Related errors


AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31). Data as JSON: /api/errors/723574956d8766ec. Report an issue: GitHub.