{"record":{"id":"ab24c1d2ed3c7743","repo":"siyuan-note/siyuan","slug":"property-q-x-mcp-header-value-q-is-not-a-valid","errorCode":null,"errorMessage":"property %q: x-mcp-header value %q is not a valid HTTP field name","messagePattern":"property %q: x-mcp-header value %q is not a valid HTTP field name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/mcp/tools/validation.go","lineNumber":250,"sourceCode":"\t\t\t\tcontinue\n\t\t\t}\n\t\t\tpath := propertyName\n\t\t\tif prefix != \"\" {\n\t\t\t\tpath = prefix + \".\" + propertyName\n\t\t\t}\n\t\t\tif rawHeader, exists := property[\"x-mcp-header\"]; exists {\n\t\t\t\theader, ok := rawHeader.(string)\n\t\t\t\tif !ok || header == \"\" {\n\t\t\t\t\treturn fmt.Errorf(`property %q: x-mcp-header must be a non-empty string`, path)\n\t\t\t\t}\n\t\t\t\tpropertyType, _ := property[\"type\"].(string)\n\t\t\t\tif propertyType != \"string\" && propertyType != \"integer\" && propertyType != \"boolean\" {\n\t\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\t`property %q: x-mcp-header can only be applied to primitive types (integer, string, boolean), got %q`,\n\t\t\t\t\t\tpath, propertyType)\n\t\t\t\t}\n\t\t\t\tif !validHTTPFieldName(header) {\n\t\t\t\t\treturn fmt.Errorf(`property %q: x-mcp-header value %q is not a valid HTTP field name`, path, header)\n\t\t\t\t}\n\t\t\t\tnormalized := strings.ToLower(header)\n\t\t\t\tif seen[normalized] {\n\t\t\t\t\treturn fmt.Errorf(`property %q: duplicate x-mcp-header value %q`, path, header)\n\t\t\t\t}\n\t\t\t\tseen[normalized] = true\n\t\t\t}\n\t\t\tnested, _ := property[\"properties\"].(map[string]any)\n\t\t\tif err := walk(nested, path); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn walk(properties, \"\")\n}\n\nfunc validHTTPFieldName(name string) bool {","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/mcp/tools/validation.go#L232-L268","documentation":"Thrown by validateParamHeaderAnnotations when the x-mcp-header string fails validHTTPFieldName: every character must be a visible VCHAR token per RFC 7230 (ASCII letters, digits, or one of !#$%&'*+-.^_`|~), and no character may exceed U+007F. This prevents malformed or injected header names from reaching the HTTP backend.","triggerScenarios":"Registering a tool with an x-mcp-header value containing spaces, colons, non-ASCII characters, or control characters — e.g. \"X Custom\", \"X-Header:\", or \"ヘッダー\".","commonSituations":"Including a colon in the header name (the separator belongs only in the serialized line); using spaces or hyphens-with-spaces; copying a localized header label into the annotation; trailing whitespace.","solutions":["Use a valid RFC 7230 token: ASCII letters, digits, and hyphens only, no spaces or colons (e.g. \"X-Request-Id\").","Strip whitespace and any trailing colon before setting the value.","Avoid non-ASCII characters in header names — HTTP field names are token-only."],"exampleFix":"// before\n{\"x-mcp-header\": \"X Custom Header:\"}\n// after\n{\"x-mcp-header\": \"X-Custom-Header\"}","handlingStrategy":"validation","validationCode":"func validToken(name string) bool {\n    if name == \"\" { return false }\n    for _, r := range name {\n        if r > 127 { return false }\n        ok := (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') ||\n            strings.ContainsRune(\"!#$%&'*+-.^_`|~\", r)\n        if !ok { return false }\n    }\n    return true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use ASCII token characters only (letters, digits, hyphens).","Never include spaces, colons, or non-ASCII characters in header names.","Generate header names from a vetted allow-list."],"tags":["mcp","json-schema","http-header","rfc-7230","validation"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}