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

  1. Pass a JSON object string, e.g. `ocr config set mcp-servers.myserver.headers '{"Authorization":"Bearer token"}'`
  2. Single-quote the value in the shell so braces and inner double quotes survive
  3. 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

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


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/a89fa56de79bb2c4. Report an issue: GitHub.