{"record":{"id":"8967609dce535c73","repo":"vitest-dev/vitest","slug":"expected-ip-address-received-address","errorCode":null,"errorMessage":"Expected IP address, received ${address}","messagePattern":"Expected IP address, received (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/runtime/vm/esm-executor.ts","lineNumber":484,"sourceCode":"    }\n\n    if (mime === 'application/json') {\n      const module = this.createJsonModule(identifier, code as string)\n      this.moduleCache.set(identifier, module)\n      return module\n    }\n\n    return this.createEsModule(identifier, () => code as string)\n  }\n}\n\nfunction IPnumber(address: string) {\n  const ip = address.match(/^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$/)\n  if (ip) {\n    return (+ip[1] << 24) + (+ip[2] << 16) + (+ip[3] << 8) + +ip[4]\n  }\n\n  throw new Error(`Expected IP address, received ${address}`)\n}\n\nfunction IPmask(maskSize: number) {\n  return -1 << (32 - maskSize)\n}\n","sourceCodeStart":466,"sourceCodeEnd":490,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/runtime/vm/esm-executor.ts#L466-L490","documentation":"The helper IPnumber() parses an IPv4 dotted-quad via /^\\d+\\.\\d+\\.\\d+\\.\\d+$/. If the string does not match it throws 'Expected IP address, received ...'. It is invoked from the http-host check in createNetworkModule() on url.hostname whenever that hostname is neither 'localhost' nor '::1'.","triggerScenarios":"An http:// import in the vm pool whose hostname is a domain name (e.g. http://example.com/x.js) or a non-IPv4 literal (e.g. an IPv6 address other than ::1). Because the hostname is not 'localhost' or '::1', IPnumber(url.hostname) is called on a non-IPv4 string and throws before the [361] comparison can run.","commonSituations":"Importing from a CDN or named host over http in the vm pool. Note this masks error [361]: for domain hostnames you get [362] rather than the friendlier 'use https instead' message.","solutions":["Switch the http import to https; https imports are not subject to the IP check.","Use a loopback hostname (localhost or 127.0.0.1) so IPnumber is never reached.","Use a non-vm pool (threads/forks) if you must import over http from a named host.","Avoid remote http imports in tests entirely; fetch the file and import it locally."],"exampleFix":"// before\nawait import('http://my-service.local/fixture.js')\n\n// after\nawait import('https://my-service.local/fixture.js')","handlingStrategy":"validation","validationCode":"function isIPv4(s){ return /^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$/.test(s) }\nconst h = new URL(u).hostname\nif (u.startsWith('http://') && h!=='localhost' && h!=='::1' && !isIPv4(h)) {\n  throw new Error('http import requires an IPv4/localhost host or https')\n}","typeGuard":"function isValidIPv4(address){\n  const m = address.match(/^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$/)\n  return !!m && m.slice(1).every(n => +n >= 0 && +n <= 255)\n}","tryCatchPattern":null,"preventionTips":["Avoid http:// imports with domain hostnames in the vm pool.","Use https:// so the IP-number check is bypassed.","Run remote-dependent tests in threads/forks pools."],"tags":["network","http","ipv4","vm","internal-helper"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}