{"record":{"id":"0af880d355edcbc6","repo":"grafana/k6","slug":"proxy-server-must-be-set","errorCode":null,"errorMessage":"proxy.server must be set","messagePattern":"proxy\\.server must be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/browser_context_options.go","lineNumber":68,"sourceCode":"type Geolocation struct {\n\tLatitude  float64 `js:\"latitude\"`\n\tLongitude float64 `js:\"longitude\"`\n\tAccuracy  float64 `js:\"accuracy\"`\n}\n\n// ProxyOptions represents proxy configuration for a browser context.\ntype ProxyOptions struct {\n\tServer string `js:\"server\"`\n\tBypass string `js:\"bypass\"`\n}\n\n// Validate validates the [ProxyOptions].\nfunc (p *ProxyOptions) Validate() error {\n\tif p == nil {\n\t\treturn nil\n\t}\n\tif strings.TrimSpace(p.Server) == \"\" {\n\t\treturn fmt.Errorf(\"proxy.server must be set\")\n\t}\n\treturn nil\n}\n\n// Validate validates the [Geolocation].\nfunc (g *Geolocation) Validate() error {\n\tif g.Longitude < -180 || g.Longitude > 180 {\n\t\treturn fmt.Errorf(`invalid longitude \"%.2f\": precondition -180 <= LONGITUDE <= 180 failed`, g.Longitude)\n\t}\n\tif g.Latitude < -90 || g.Latitude > 90 {\n\t\treturn fmt.Errorf(`invalid latitude \"%.2f\": precondition -90 <= LATITUDE <= 90 failed`, g.Latitude)\n\t}\n\tif g.Accuracy < 0 {\n\t\treturn fmt.Errorf(`invalid accuracy \"%.2f\": precondition 0 <= ACCURACY failed`, g.Accuracy)\n\t}\n\treturn nil\n}\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/browser_context_options.go#L50-L86","documentation":"Validation error from ProxyOptions.Validate: a proxy block was supplied for a browser context but its server field is empty (or whitespace-only). k6 requires the CDP endpoint of the proxy to be configured whenever the proxy option is present — supplying the block at all signals intent, and an empty server is treated as a configuration mistake. A nil proxy block passes validation.","triggerScenarios":"browser.newContext({ proxy: {} }), { proxy: { bypass: 'localhost' } }, or proxy: { server: '   ' }. Also triggered when server is set via a variable that resolves to an empty string.","commonSituations":"Config scaffolding where the proxy option is added before the proxy URL is actually wired in; env-driven proxy config where the variable name is misspelled and yields ''; copying an example that only showed the bypass field.","solutions":["Set server to the proxy endpoint: proxy: { server: 'http://myproxy.corp:8080' }.","If you don't need a proxy, remove the proxy block entirely (an absent block is valid; an empty one is not).","When proxy config comes from env vars, fail fast with a clear message when the variable is unset instead of passing an empty server."],"exampleFix":"// before\nconst context = browser.newContext({ proxy: { bypass: 'localhost' } });\n\n// after\nconst context = browser.newContext({\n  proxy: { server: 'http://myproxy:8080', bypass: 'localhost' },\n});","handlingStrategy":"validation","validationCode":"const proxyOpts = proxyServerFromEnv ? { server: proxyServerFromEnv, bypass } : undefined;\nif (proxyOpts && !String(proxyOpts.server).trim()) {\n  throw new Error('proxy.server must be a non-empty proxy URL, e.g. http://proxy:8080');\n}\nbrowser.newContext({ proxy: proxyOpts });","typeGuard":"function isUsableProxyOptions(p) {\n  return p == null || (typeof p.server === 'string' && p.server.trim() !== '');\n}","tryCatchPattern":null,"preventionTips":["Omit the proxy block entirely when no proxy is needed.","Fail fast on empty env-provided proxy URLs instead of passing them through.","Include the server field in every proxy config example and review."],"tags":["proxy","validation","configuration","browser-context"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}