{"record":{"id":"abe0423cf7caea67","repo":"siyuan-note/siyuan","slug":"failed-to-export-headers-w","errorCode":null,"errorMessage":"failed to export headers: %w","messagePattern":"failed to export headers: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_client.go","lineNumber":75,"sourceCode":"\n\t\tif goja.IsString(call.Argument(0)) {\n\t\t\tpath = call.Argument(0).String()\n\t\t} else {\n\t\t\targErr = fmt.Errorf(\"path required\")\n\t\t}\n\t\tif argErr == nil && !strings.HasPrefix(path, \"/\") {\n\t\t\targErr = fmt.Errorf(\"path must start with /\")\n\t\t}\n\t\tif argErr == nil {\n\t\t\tif init := call.Argument(1); isJsValueNotNull(init) {\n\t\t\t\tif initObj := init.ToObject(rt); initObj != nil {\n\t\t\t\t\tif m := initObj.Get(\"method\"); goja.IsString(m) {\n\t\t\t\t\t\tmethod = m.String()\n\t\t\t\t\t}\n\n\t\t\t\t\tif h := initObj.Get(\"headers\"); isJsValueNotNull(h) {\n\t\t\t\t\t\tif exportErr := rt.ExportTo(h, &headers); exportErr != nil {\n\t\t\t\t\t\t\targErr = fmt.Errorf(\"failed to export headers: %w\", exportErr)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif argErr == nil {\n\t\t\t\t\t\tif b := initObj.Get(\"body\"); isJsValueNotNull(b) {\n\t\t\t\t\t\t\tif goja.IsString(b) {\n\t\t\t\t\t\t\t\tbodyString = new(b.String())\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tbody := b.Export()\n\t\t\t\t\t\t\t\tif arrayBuffer, ok := body.(goja.ArrayBuffer); ok {\n\t\t\t\t\t\t\t\t\tsrc := arrayBuffer.Bytes()\n\t\t\t\t\t\t\t\t\tbodyBytes = new(src)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/plugin/api_client.go#L57-L93","documentation":"Thrown when the headers field of the fetch init object cannot be exported to map[string]string via goja's ExportTo. fetch requires headers as a flat string-to-string map; anything goja cannot coerce into that shape (arrays of pairs, nested objects, a Headers instance, non-string scalars) fails the export at api_client.go:74.","triggerScenarios":"Passing headers as an array of pairs ([['Content-Type','application/json']]) like the browser Headers constructor, a nested object ({ a: { b: 'c' } }), a number-valued header, or an actual fetch Headers object.","commonSituations":"Developer ports browser fetch code that used new Headers(...) or an entries array, or sets a header to a number expecting automatic coercion (goja's ExportTo to map[string]string does not coerce).","solutions":["Pass headers as a plain object of string keys to string values: { 'Content-Type': 'application/json' }.","If you have an array of pairs, convert first: Object.fromEntries(pairs).","Stringify any non-string header value before putting it in the map."],"exampleFix":"// before\nawait siyuan.client.fetch('/api/x', { headers: [['Content-Type','application/json']] });\n// after\nawait siyuan.client.fetch('/api/x', { headers: { 'Content-Type': 'application/json' } });","handlingStrategy":"type-guard","validationCode":"function normalizeHeaders(h) {\n  if (h == null) return {};\n  const out = {};\n  for (const [k, v] of Object.entries(h)) out[String(k)] = String(v);\n  return out;\n}\nawait siyuan.client.fetch('/api/x', { headers: normalizeHeaders(init.headers) });","typeGuard":"const isStringMap = (v) => v != null && typeof v === 'object' && !Array.isArray(v) && Object.values(v).every(x => typeof x === 'string');","tryCatchPattern":null,"preventionTips":["Never pass a Headers instance or entries array; use a plain object.","Coerce all header values to strings before calling.","Avoid nested objects in headers."],"tags":["client-fetch","validation","headers","goja"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}