{"record":{"id":"c50479d07e2e3765","repo":"golang/go","slug":"invalid-format-missing-empty-line-after-urls","errorCode":null,"errorMessage":"invalid format: missing empty line after URLs","messagePattern":"invalid format: missing empty line after URLs","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/auth/userauth.go","lineNumber":63,"sourceCode":"\treturn credentials, nil\n}\n\n// parseUserAuth parses the output from a GOAUTH command and\n// returns a mapping of prefix → http.Header without the leading \"https://\"\n// or an error if the data does not follow the expected format.\n// Returns a nil error and an empty map if the data is empty.\n// See the expected format in 'go help goauth'.\nfunc parseUserAuth(data string) (map[string]http.Header, error) {\n\tcredentials := make(map[string]http.Header)\n\tfor data != \"\" {\n\t\tvar line string\n\t\tvar ok bool\n\t\tvar urls []string\n\t\t// Parse URLS first.\n\t\tfor {\n\t\t\tline, data, ok = strings.Cut(data, \"\\n\")\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid format: missing empty line after URLs\")\n\t\t\t}\n\t\t\tif line == \"\" {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tu, err := url.ParseRequestURI(line)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"could not parse URL %s: %v\", line, err)\n\t\t\t}\n\t\t\turls = append(urls, u.String())\n\t\t}\n\t\t// Parse Headers second.\n\t\theader := make(http.Header)\n\t\tfor {\n\t\t\tline, data, ok = strings.Cut(data, \"\\n\")\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid format: missing empty line after headers\")\n\t\t\t}\n\t\t\tif line == \"\" {","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/auth/userauth.go#L45-L81","documentation":"Raised inside parseUserAuth while collecting URL lines. The loop cuts input on `\\n`; if strings.Cut returns ok=false (no more newlines) before an empty line terminates the URL list, the URL section was never closed and parsing aborts with this message.","triggerScenarios":"The GOAUTH command output contains URL lines but no terminating blank line, or the input ends mid-URL-list without a final newline.","commonSituations":"Output written without a trailing `\\n\\n`; the command emits URLs only and forgets the blank separator; a single block missing its closing empty line.","solutions":["Terminate every URL list with a blank line.","End each credential block with `\\n\\n` (URLs, blank, headers, blank).","Validate output locally before relying on it: pipe the command's stdout through a parser in a test."],"exampleFix":"// malformed: no blank line after URL\nhttps://example.com\nAuthorization: Bearer x\n// fixed\nhttps://example.com\n\nAuthorization: Bearer x\n\n","handlingStrategy":"validation","validationCode":"// Ensure the URL list is blank-line-terminated.\nfunc endsURLBlock(s string) bool {\n    return strings.Contains(s, \"\\n\\n\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Terminate each URL list with a blank line.","End every credential block with `\\n\\n`.","Unit-test the command's stdout against parseUserAuth."],"tags":["go-toolchain","goauth","authentication","parsing","format","custom-command"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}