alibaba/open-code-review · error
invalid headers for %s: %w
Error message
invalid headers for %s: %w
What it means
setMCPServerValue wraps any failure from parseMCPHeaders with "invalid headers for <server>: ..." when the CLI user sets the `headers` field of an MCP server via `ocr config set mcp-servers.<name>.headers`. parseMCPHeaders requires a JSON object of string key-value pairs, so wrapping preserves the underlying cause (bad JSON, empty key, empty value).
Source
Thrown at cmd/opencodereview/config_cmd.go:903
case "url":
if value == "" {
return fmt.Errorf("MCP server URL cannot be empty")
}
parsed, err := url.Parse(value)
if err != nil {
return fmt.Errorf("invalid MCP server URL %q: %w", value, err)
}
if parsed.Scheme != "http" && parsed.Scheme != "https" {
return fmt.Errorf("MCP server URL must use http or https scheme, got %q", parsed.Scheme)
}
if parsed.Host == "" {
return fmt.Errorf("MCP server URL %q must include a host", value)
}
entry.URL = value
case "headers":
parsed, err := parseMCPHeaders(value)
if err != nil {
return fmt.Errorf("invalid headers for %s: %w", key, err)
}
entry.Headers = parsed
case "tools":
var tools []string
if err := json.Unmarshal([]byte(value), &tools); err != nil {
return fmt.Errorf("invalid JSON array for %s: %w", key, err)
}
seen := make(map[string]struct{}, len(tools))
filtered := make([]string, 0, len(tools))
for _, t := range tools {
if t == "" {
return fmt.Errorf("tool names in %s must not be empty", key)
}
if _, dup := seen[t]; dup {
continue
}
seen[t] = struct{}{}
filtered = append(filtered, t)View on GitHub (pinned to 5cf97d0d15)
Solutions
- Pass a JSON object string, e.g. `ocr config set mcp-servers.myserver.headers '{"Authorization":"Bearer token"}'`
- Single-quote the value in the shell so braces and inner double quotes survive
- Inspect the wrapped cause after `invalid headers for ...:` — it says whether the JSON was unparseable or a key/value was empty
Example fix
// before
ocr config set mcp-servers.remote.headers Authorization=Bearer\ abc
// after
ocr config set mcp-servers.remote.headers '{"Authorization": "Bearer abc"}' Defensive patterns
Strategy: validation
Validate before calling
func validHeaders(s string) bool {
var m map[string]string
if json.Unmarshal([]byte(s), &m) != nil { return false }
for k, v := range m { if k == "" || v == "" { return false } }
return true
} Type guard
func isStringMap(v any) bool { _, ok := v.(map[string]string); return ok } Try / catch
if err := setMCPServerValue(cfg, name, "headers", raw); err != nil {
var perr *json.SyntaxError
if errors.As(err, &perr) { /* show syntax offset */ }
return err
} Prevention
- Always pass headers as a single-quoted JSON object in the shell
- Keep header values non-empty; interpolate env vars with ${VAR} defaults
- Round-trip the value through `jq -c .` before setting it
When it happens
Trigger: Running the config set command with headers value that is not a valid JSON object, e.g. `ocr config set mcp-servers.myserver.headers "Bearer abc"` (bare string instead of object) or JSON containing an empty key/value.
Common situations: Quoting mistakes in the shell that strip the JSON braces; hand-writing headers as a plain string; pasting a single Authorization header instead of an object; forgetting to escape inner quotes.
Related errors
- MCP server %q not found
- invalid JSON for llm.extra_body: %w
- invalid JSON array for %s: %w
- tool names in %s must not be empty
- unknown MCP server field %q: supported fields are type, comm
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/a89fa56de79bb2c4.
Report an issue: GitHub.