siyuan-note/siyuan · error

property : x-mcp-header value is not a valid HTTP field name

Error message

property %q: x-mcp-header value %q is not a valid HTTP field name

What it means

The value of x-mcp-header must be a syntactically valid HTTP field name, checked by validHTTPFieldName (token characters per RFC 7230). Values containing spaces, colons, non-ASCII, or other illegal characters are rejected before the header can ever be sent.

Solutions

  1. Use a valid RFC 7230 token as the header name, e.g. "X-Trace-Id"
  2. Remove any colon/space/value portion — only the field name is allowed
  3. Match the case pattern of standard headers (validation may still accept any valid token; normalize later)

Example fix

// before
{"x-mcp-header":"Content Type: abc"}
// after
{"x-mcp-header":"Content-Type"}
Defensive patterns

Strategy: validation

Validate before calling

const TOKEN_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
function checkHeaderNames(schema) {
  for (const prop of Object.values(schema.properties || {})) {
    if (typeof prop['x-mcp-header'] === 'string' && !TOKEN_RE.test(prop['x-mcp-header'])) {
      throw new Error(`invalid HTTP field name: ${prop['x-mcp-header']}`);
    }
  }
}

Type guard

const isValidHeaderName = (s) => typeof s === 'string' && /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(s);

Try / catch

try { registerTool(schema) } catch (e) { if (String(e).includes('valid HTTP field name')) fixHeaderNameAndRetry(schema); else throw e; }

Prevention

When it happens

Trigger: A schema property declares x-mcp-header with a value like "Content Type", "x-custom:header", or one containing unicode/special characters, then tool schema validation runs.

Common situations: Typos in header names, pasting a full header line ("X-Foo: bar") instead of the name, localizing header names, or using underscores-containing names if the validator forbids them.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/ab24c1d2ed3c7743. Report an issue: GitHub.

Appendix: source

Thrown at kernel/mcp/tools/validation.go:249

			if !ok {
				continue
			}
			path := propertyName
			if prefix != "" {
				path = prefix + "." + propertyName
			}
			if rawHeader, exists := property["x-mcp-header"]; exists {
				header, ok := rawHeader.(string)
				if !ok || header == "" {
					return fmt.Errorf(`property %q: x-mcp-header must be a non-empty string`, path)
				}
				propertyType, _ := property["type"].(string)
				if propertyType != "string" && propertyType != "integer" && propertyType != "boolean" {
					return fmt.Errorf(
						`property %q: x-mcp-header can only be applied to primitive types (integer, string, boolean), got %q`,
						path, propertyType)
				}
				if !validHTTPFieldName(header) {
					return fmt.Errorf(`property %q: x-mcp-header value %q is not a valid HTTP field name`, path, header)
				}
				normalized := strings.ToLower(header)
				if seen[normalized] {
					return fmt.Errorf(`property %q: duplicate x-mcp-header value %q`, path, header)
				}
				seen[normalized] = true
			}
			nested, _ := property["properties"].(map[string]any)
			if err := walk(nested, path); err != nil {
				return err
			}
		}
		return nil
	}
	return walk(properties, "")
}

View on GitHub (pinned to 9f775e8a12)