{"record":{"id":"4444a35bb311b6c1","repo":"alibaba/open-code-review","slug":"unsupported-auth-header-value-q-expected-x-api","errorCode":null,"errorMessage":"unsupported auth_header value %q; expected \"x-api-key\" or \"authorization\"","messagePattern":"unsupported auth_header value %q; expected \"x-api-key\" or \"authorization\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/llm/resolver.go","lineNumber":833,"sourceCode":"\t\t}\n\t}\n\treturn false\n}\n\n// NormalizeAuthHeader normalizes an auth header value to a canonical form.\n// It returns an error for unrecognized values.\nfunc NormalizeAuthHeader(header string) (string, error) {\n\theader = strings.TrimSpace(header)\n\tif header == \"\" {\n\t\treturn \"\", nil\n\t}\n\tswitch strings.ToLower(header) {\n\tcase \"x-api-key\":\n\t\treturn \"x-api-key\", nil\n\tcase \"authorization\", \"bearer\":\n\t\treturn \"authorization\", nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"unsupported auth_header value %q; expected \\\"x-api-key\\\" or \\\"authorization\\\"\", header)\n\t}\n}\n\n// reservedHeaders are HTTP headers that extra_headers must not override.\n// They are managed by dedicated config fields (auth_header, auth_token) or set automatically by the SDK.\n// Letting extra_headers clobber them would cause confusing auth/content-type failures with no clear error.\nvar reservedHeaders = map[string]bool{\n\t\"authorization\": true,\n\t\"x-api-key\":     true,\n\t\"content-type\":  true,\n\t\"user-agent\":    true,\n}\n\n// ParseExtraHeaders parses a string of comma-separated key=value pairs into a dictionary.\n// Values may be double-quoted to include commas, e.g. X-Forwarded-For=\"1.2.3.4,5.6.7.8\".\n// Reserved header names (authorization, x-api-key, content-type, user-agent) are rejected\n// to prevent accidental override of auth or content-type set by the SDK.\nfunc ParseExtraHeaders(raw string) (map[string]string, error) {","sourceCodeStart":815,"sourceCodeEnd":851,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/llm/resolver.go#L815-L851","documentation":"NormalizeAuthHeader validates the llm.auth_header field (used when protocol is anthropic). Only \"x-api-key\", \"authorization\", and the alias \"bearer\" are accepted, compared case-insensitively; anything else returns this error, later wrapped as 'OCR config file: unsupported auth_header value ...'.","triggerScenarios":"A completed [llm] block with protocol = anthropic and auth_header set to a value other than x-api-key/authorization/bearer, e.g. auth_header = \"x-goog-api-key\" or \"Api-Key\".","commonSituations":"Copying an auth header name from another provider's SDK into the config; misspelling the header (\"x_api_key\", \"auth-header\"); leaving a custom gateway header name in place after switching protocols.","solutions":["Change auth_header to exactly \"x-api-key\" or \"authorization\" (\"bearer\" is accepted as an alias for authorization); casing is ignored","Remove the auth_header key entirely to use the protocol default","If you need a non-standard auth header for a gateway, pass it via extra_headers instead — but note auth-related reserved headers are protected"],"exampleFix":"// before (config file)\nauth_header = \"x_api_key\"\n// after\nauth_header = \"x-api-key\"","handlingStrategy":"validation","validationCode":"allowed := map[string]bool{\"x-api-key\": true, \"authorization\": true, \"bearer\": true}\nif h := strings.TrimSpace(cfg.Llm.AuthHeader); h != \"\" && !allowed[strings.ToLower(h)] {\n    return fmt.Errorf(\"auth_header must be x-api-key or authorization, got %q\", h)\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := llm.ResolveEndpoint(cfg, \"\"); err != nil {\n    if strings.Contains(err.Error(), \"unsupported auth_header\") {\n        // edit auth_header in the config to a supported value\n    }\n}","preventionTips":["Only use x-api-key or authorization (bearer alias); casing does not matter","Omit auth_header to inherit the protocol default","Put gateway-specific headers in extra_headers, not auth_header"],"tags":["config","validation","http-headers","auth"],"backgroundTag":"invalid-config-value","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}