{"record":{"id":"54d5852a11a2f92f","repo":"alibaba/open-code-review","slug":"header-value-for-q-must-not-be-empty","errorCode":null,"errorMessage":"header value for %q must not be empty","messagePattern":"header value for %q must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/opencodereview/config_cmd.go","lineNumber":946,"sourceCode":"\t}\n\n\tcfg.MCPServers[name] = entry\n\treturn nil\n}\n\n// parseMCPHeaders parses a JSON object of header key-value pairs.\n// Example: {\"Authorization\": \"Bearer $TOKEN\", \"X-Custom\": \"value\"}\nfunc parseMCPHeaders(value string) (map[string]string, error) {\n\tvar m map[string]string\n\tif err := json.Unmarshal([]byte(value), &m); err != nil {\n\t\treturn nil, fmt.Errorf(\"expected JSON object: %w\", err)\n\t}\n\tfor k, v := range m {\n\t\tif k == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"header name must not be empty\")\n\t\t}\n\t\tif v == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"header value for %q must not be empty\", k)\n\t\t}\n\t}\n\treturn m, nil\n}\n\nfunc (c *Config) ensureTelemetry() {\n\tif c.Telemetry == nil {\n\t\tc.Telemetry = &TelemetryConfig{}\n\t}\n}\n","sourceCodeStart":928,"sourceCodeEnd":957,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/cmd/opencodereview/config_cmd.go#L928-L957","documentation":"parseMCPHeaders rejects a header whose value is an empty string with \"header value for <name> must not be empty\". An empty header value is almost always an unset secret or environment-variable expansion, so the config command fails fast instead of sending a useless Authorization header at runtime.","triggerScenarios":"`ocr config set mcp-servers.myserver.headers '{\"Authorization\":\"\"}'` — commonly because $TOKEN was unset/unexported when the shell expanded it, or a secret was never filled in.","commonSituations":"Environment variable not exported in the current shell; CI secret not configured; placeholder like <token> replaced with empty string by a script.","solutions":["Set the variable before expansion: `export TOKEN=...` then rerun the set command with '{\"Authorization\":\"Bearer $TOKEN\"}'","Alternatively set the entry and rely on runtime env expansion if supported by the entry format","Verify the secret exists in CI/local environment before configuring"],"exampleFix":"// before\nocr config set mcp-servers.myserver.headers '{\"Authorization\": \"Bearer $TOKEN\"}'   # TOKEN unset -> value \"\"\n// after\nexport TOKEN=ghp_xxx && ocr config set mcp-servers.myserver.headers '{\"Authorization\": \"Bearer $TOKEN\"}'","handlingStrategy":"validation","validationCode":"func valuesNonEmpty(s string) bool {\n    var m map[string]string\n    if json.Unmarshal([]byte(s), &m) != nil { return false }\n    for k, v := range m { if v == \"\" { return false } }\n    return true\n}","typeGuard":"func missingSecret(m map[string]string, key string) bool { return m[key] == \"\" }","tryCatchPattern":"if err := setMCPServerValue(cfg, name, \"headers\", raw); err != nil {\n    if strings.Contains(err.Error(), \"must not be empty\") { /* re-export the secret and retry */ }\n    return err\n}","preventionTips":["Export the secret before shell expansion: `export TOKEN=...`","Use ${TOKEN:?unset} in bash to fail fast when the var is empty","Prefer runtime env expansion over baking secret literals into config"],"tags":["config","validation","http-headers","secrets"],"backgroundTag":"empty-env-var-substitution","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}