{"record":{"id":"9a9373c71f07403f","repo":"siyuan-note/siyuan","slug":"parses-request-s-failed-map-string-json-rawmessage","errorCode":null,"errorMessage":"Parses request [%s] failed: map[string]json.RawMessage","messagePattern":"Parses request \\[(.+?)\\] failed: map\\[string\\]json\\.RawMessage","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/bazaar.go","lineNumber":956,"sourceCode":"\t\t\treturn request, err\n\t\t}\n\t\tif request.Frontend, err = bazaarString(fields, \"frontend\", false, false); err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\tif request.Keyword, err = bazaarString(fields, \"keyword\", false, false); err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\tif request.PackageName, err = bazaarString(fields, \"packageName\", true, true); err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\treturn request, nil\n\t}\n}\n\nfunc bazaarRequestFields(reader io.Reader, path string) (map[string]json.RawMessage, error) {\n\tfields, err := blockRequestFields(reader, path)\n\tif err != nil {\n\t\treturn nil, errors.New(strings.ReplaceAll(err.Error(), \"map[string]json.RawMessage\", \"map[string]interface {}\"))\n\t}\n\treturn fields, nil\n}\n","sourceCodeStart":938,"sourceCodeEnd":960,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/bazaar.go#L938-L960","documentation":"This error wraps a JSON body parse failure for bazaar endpoints. The underlying decoder parses the body into map[string]json.RawMessage; this wrapper rewrites the type name in the message from map[string]json.RawMessage back to map[string]interface {} so legacy clients matching on the old message text keep working. The actual cause is malformed or non-object JSON in the request body.","triggerScenarios":"Sending a bazaar API request whose body is not a JSON object (e.g. a JSON array, bare string/number, or invalid JSON), which makes blockRequestFields fail, then surfaced via bazaarRequestFields with the legacy-normalized message.","commonSituations":"Clients posting arrays of packages instead of an object with a packageNames key, Content-Type/encoding mismatches producing truncated bodies, or tests asserting on the legacy error text.","solutions":["Ensure the request body is a single valid JSON object (starts with {), not an array or scalar.","Validate the JSON with a parser/linter before sending.","Check for truncation: streaming, chunked encodings, or proxy stripping that cuts the body off.","If matching the error text in tests, note the type name is normalized to map[string]interface {}."],"exampleFix":"// before\n[\"siyuan-plugin-a\", \"siyuan-plugin-b\"]\n// after\n{\"packageNames\": [\"siyuan-plugin-a\", \"siyuan-plugin-b\"]}","handlingStrategy":"try-catch","validationCode":"let parsed; try { parsed = JSON.parse(bodyString); } catch { throw new Error(\"body is not valid JSON\"); }\nif (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) { throw new Error(\"body must be a JSON object\"); }","typeGuard":"const isJsonObject = (v) => v !== null && typeof v === \"object\" && !Array.isArray(v);","tryCatchPattern":"try {\n  await post(path, body);\n} catch (e) {\n  if (String(e.message).includes(\"Parses request\")) {\n    console.error(\"Non-object or malformed JSON body:\", bodyString);\n  } else { throw e; }\n}","preventionTips":["Always serialize with JSON.stringify, never string concatenation","Assert the payload is a JSON object before sending","Set Content-Type: application/json","Watch for proxies or encoders that alter the body"],"tags":["json","parsing","api","compatibility"],"backgroundTag":"json-decode-failed","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"}