{"record":{"id":"33a590906ed7aa43","repo":"juanfont/headscale","slug":"directory-is-required","errorCode":null,"errorMessage":"directory is required","messagePattern":"directory is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/mapresponses/main.go","lineNumber":21,"sourceCode":"import (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/creachadair/command\"\n\t\"github.com/creachadair/flax\"\n\t\"github.com/juanfont/headscale/hscontrol/mapper\"\n\t\"github.com/juanfont/headscale/integration/integrationutil\"\n)\n\ntype MapConfig struct {\n\tDirectory string `flag:\"directory,Directory to read map responses from\"`\n}\n\nvar (\n\tmapConfig            MapConfig\n\terrDirectoryRequired = errors.New(\"directory is required\")\n)\n\nfunc main() {\n\troot := command.C{\n\t\tName: \"mapresponses\",\n\t\tHelp: \"MapResponses is a tool to map and compare map responses from a directory\",\n\t\tCommands: []*command.C{\n\t\t\t{\n\t\t\t\tName:     \"online\",\n\t\t\t\tHelp:     \"\",\n\t\t\t\tUsage:    \"run [test-pattern] [flags]\",\n\t\t\t\tSetFlags: command.Flags(flax.MustBind, &mapConfig),\n\t\t\t\tRun:      runOnline,\n\t\t\t},\n\t\t\tcommand.HelpCommand(nil),\n\t\t},\n\t}\n","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/cmd/mapresponses/main.go#L3-L39","documentation":"Wrapped error from doLoginURLWithClient when io.ReadAll on the login response body fails. The request itself succeeded (resp is non-nil and is closed via defer), but streaming the body errored — typically a dropped connection mid-body.","triggerScenarios":"The control server or OIDC provider closes the connection while the response body is being read; keep-alive race, proxy or Docker network interruption, or a very large body hitting a read deadline.","commonSituations":"Flaky Docker networking in CI, headscale restarting mid-response, reverse proxy timeouts when the login handler is slow.","solutions":["Re-run — this is almost always a transient transport failure.","If persistent, capture headscale/provider logs at the timestamp to see if the handler crashed mid-response.","Check for proxies between the test and containers adding body-size or idle limits."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"reading response body\") {\n    // transient transport drop: retry the whole login GET once\n}","preventionTips":["Expect occasional mid-body drops in Docker CI and retry the login step.","Keep control-server handlers fast to avoid proxy/read deadlines."],"tags":["integration","http","network","transient"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}