{"record":{"id":"f322d8479582459c","repo":"argoproj/argo-workflows","slug":"additional-headers-must-be-colon-separated-s","errorCode":null,"errorMessage":"additional headers must be colon(:)-separated: %s","messagePattern":"additional headers must be colon\\(:\\)-separated: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiclient/http1/facade.go","lineNumber":218,"sourceCode":"\tif r.StatusCode == http.StatusOK {\n\t\treturn nil\n\t}\n\tx := &struct {\n\t\tCode    codes.Code `json:\"code\"`\n\t\tMessage string     `json:\"message\"`\n\t}{}\n\tif err := json.NewDecoder(r.Body).Decode(x); err == nil {\n\t\treturn status.Error(x.Code, x.Message)\n\t}\n\treturn status.Error(codes.Internal, fmt.Sprintf(\": %v\", r))\n}\n\nfunc parseHeaders(headerStrings []string) (http.Header, error) {\n\theaders := http.Header{}\n\tfor _, kv := range headerStrings {\n\t\titems := strings.Split(kv, \":\")\n\t\tif len(items)%2 == 1 {\n\t\t\treturn nil, fmt.Errorf(\"additional headers must be colon(:)-separated: %s\", kv)\n\t\t}\n\t\theaders.Add(items[0], items[1])\n\t}\n\treturn headers, nil\n}\n","sourceCodeStart":200,"sourceCodeEnd":224,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/pkg/apiclient/http1/facade.go#L200-L224","documentation":"parseHeaders converts strings like \"Key:Value\" into an http.Header by splitting on \":\" and requiring an odd number of resulting segments (len%2==1) — i.e. exactly one colon separating key from value (values themselves may contain colons but not keys). If a header string doesn't match, it refuses with this error. It is used by the HTTP1 facade for extra headers passed to requests and event streams.","triggerScenarios":"Passing a header string to the HTTP1 client's additional-headers option (e.g. the CLI's --additional-header flag or h.headers in pkg/apiclient/http1) that contains no colon, more than one key-colon pair, or trailing whitespace forms like \"Key:\" with no value — e.g. --additional-header Authorization (missing ':token').","commonSituations":"Forgetting the value after the colon (\"X-Trace-Id:\"); putting the colon in the wrong place or quoting wrongly so the shell strips it; trying to pass multiple headers in one string instead of repeating the flag.","solutions":["Format each header as exactly \"Name:Value\" with one colon: --additional-header 'X-Foo:Bar'","Repeat the flag once per header instead of combining them in one string","Check shell quoting so the colon/value survive (quote the argument if it contains spaces or colons in the value)"],"exampleFix":"// before\n--additional-header X-Trace-Id\n// after\n--additional-header X-Trace-Id:abc123","handlingStrategy":"validation","validationCode":"func validateAdditionalHeaders(headers []string) error {\n    for _, h := range headers {\n        parts := strings.Split(h, \":\")\n        if len(parts) != 2 || parts[0] == \"\" || parts[1] == \"\" {\n            return fmt.Errorf(\"header %q must be exactly 'Name:Value'\", h)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"headers := []string{\"X-Trace-Id:abc\"}\nif err := validateAdditionalHeaders(headers); err != nil {\n    return err\n}\n// pass to client; also wrap calls that use them:\nif err != nil && strings.Contains(err.Error(), \"colon(:)-separated\") {\n    return fmt.Errorf(\"check --additional-header format 'Name:Value': %w\", err)\n}","preventionTips":["Quote header args in shells so colons/values survive","Pass one header per flag occurrence, never comma-joined","Add a startup validation of all header options before issuing requests"],"tags":["http","cli","validation","headers"],"backgroundTag":"malformed-header-format","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}