{"record":{"id":"69d6684f680d64cf","repo":"golang/go","slug":"invalid-format-missing-empty-line-after-headers","errorCode":null,"errorMessage":"invalid format: missing empty line after headers","messagePattern":"invalid format: missing empty line after headers","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/auth/userauth.go","lineNumber":79,"sourceCode":"\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 == \"\" {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tname, value, ok := strings.Cut(line, \": \")\n\t\t\tvalue = strings.TrimSpace(value)\n\t\t\tif !ok || !validHeaderFieldName(name) || !validHeaderFieldValue(value) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid format: invalid header line\")\n\t\t\t}\n\t\t\theader.Add(name, value)\n\t\t}\n\t\tmaps.Copy(credentials, mapHeadersToPrefixes(urls, header))\n\t}\n\treturn credentials, nil\n}\n\n// mapHeadersToPrefixes returns a mapping of prefix → http.Header without\n// the leading \"https://\".","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/auth/userauth.go#L61-L97","documentation":"Raised inside parseUserAuth while collecting header lines that follow the URL list and its blank line. The loop cuts on `\\n`; if strings.Cut returns ok=false (no more newlines) before a blank line terminates the header section, parsing aborts.","triggerScenarios":"The GOAUTH command output has header lines with no following blank line, or the input ends mid-header-section without a final newline.","commonSituations":"Missing trailing `\\n\\n` after the header block; output truncated; a single credential block whose closing blank line was omitted.","solutions":["Terminate every header block with a blank line.","End output with `\\n\\n` after the last header.","Validate the full structure (URLs, blank, headers, blank) in a unit test before shipping the command."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the header block is blank-line-terminated.\nfunc endsHeaderBlock(s string) bool {\n    return strings.HasSuffix(strings.TrimRight(s, \"\\n\"), \"\") && strings.Count(s, \"\\n\\n\") >= 1\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Terminate every header block with a blank line.","End output with `\\n\\n` after the last header.","Unit-test the full output shape 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-12T06:17:24.410Z"}