{"record":{"id":"11f9f935d2643f41","repo":"siyuan-note/siyuan","slug":"property-q-duplicate-x-mcp-header-value-q","errorCode":null,"errorMessage":"property %q: duplicate x-mcp-header value %q","messagePattern":"property %q: duplicate x-mcp-header value %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/mcp/tools/validation.go","lineNumber":253,"sourceCode":"\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 {\n\tif name == \"\" {\n\t\treturn false\n\t}","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/mcp/tools/validation.go#L235-L271","documentation":"Two different properties in a tool schema must not map to the same HTTP header. Validation lowercases each x-mcp-header value and keeps a seen-set; a duplicate (case-insensitive) is rejected to avoid ambiguous or overwriting header injection at request time.","triggerScenarios":"A tool schema where two properties both declare x-mcp-header with the same name (even differing in case, e.g. \"X-Auth\" and \"x-auth\") during schema validation.","commonSituations":"Copy-pasting a property and forgetting to change the header, multiple optional params intended to fill one header, generated schemas merging overlapping mappings.","solutions":["Give each property a distinct header name","If several inputs should feed one header, merge them into a single property or compose the value client-side","Remove the redundant x-mcp-header from the duplicate property"],"exampleFix":"// before\n{\"a\":{\"x-mcp-header\":\"X-Id\"},\"b\":{\"x-mcp-header\":\"x-id\"}}\n// after\n{\"a\":{\"x-mcp-header\":\"X-Id\"},\"b\":{\"x-mcp-header\":\"X-Alt-Id\"}}","handlingStrategy":"validation","validationCode":"function checkHeaderUniqueness(schema) {\n  const seen = new Set();\n  for (const prop of Object.values(schema.properties || {})) {\n    const h = prop['x-mcp-header'];\n    if (typeof h === 'string') {\n      const k = h.toLowerCase();\n      if (seen.has(k)) throw new Error(`duplicate x-mcp-header: ${h}`);\n      seen.add(k);\n    }\n  }\n}","typeGuard":"null","tryCatchPattern":"try { registerTool(schema) } catch (e) { if (String(e).includes('duplicate x-mcp-header')) renameHeadersAndRetry(schema); else throw e; }","preventionTips":["Keep a single source of truth mapping properties to headers","Compare header names case-insensitively when designing schemas","Merge multi-input values into one property instead of reusing a header"],"tags":["json-schema","mcp","http-headers","validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}