{"record":{"id":"535abbb2576bd339","repo":"siyuan-note/siyuan","slug":"parses-request-s-failed-s-sync","errorCode":null,"errorMessage":"Parses request [%s] failed: %s","messagePattern":"Parses request \\[(.+?)\\] failed: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/sync.go","lineNumber":154,"sourceCode":"\t\treturn nil\n\t}\n\tdetail := strings.ReplaceAll(err.Error(), \"apicontract.Sync\"+name, \"conf.\"+name)\n\treturn errors.New(strings.ReplaceAll(detail, \"struct field Sync\"+name+\".\", \"struct field \"+name+\".\"))\n}\n\n// syncRequestFields 保留整份请求的 JSON 数字解析、重复字段和首个对象读取语义。\nfunc syncRequestFields(reader io.Reader, path string) (fields map[string]json.RawMessage, err error) {\n\tvar raw json.RawMessage\n\terr = json.NewDecoder(reader).Decode(&raw)\n\tif err == nil {\n\t\tfields, err = legacyJSONValue[map[string]json.RawMessage](raw)\n\t}\n\tif err != nil {\n\t\tif errors.Is(err, io.EOF) {\n\t\t\terr = errors.New(\"the request body is empty or truncated (EOF)\")\n\t\t}\n\t\tdetail := strings.ReplaceAll(err.Error(), \"map[string]json.RawMessage\", \"map[string]interface {}\")\n\t\terr = fmt.Errorf(\"Parses request [%s] failed: %s\", path, detail)\n\t}\n\treturn\n}\n\nfunc init() {\n\tfor _, endpoint := range []*Endpoint[SyncEnabledRequest, Null]{&SetSyncEnable, &SetSyncPerception, &SetSyncGenerateConflictDoc} {\n\t\tpath := endpoint.definition.Path\n\t\tendpoint.decodeRequest = func(reader io.Reader) (r SyncEnabledRequest, err error) {\n\t\t\tfields, err := syncRequestFields(reader, path)\n\t\t\tif err == nil {\n\t\t\t\tr.Enabled, err = legacyField[bool](fields, \"enabled\", \"Boolean\", true)\n\t\t\t}\n\t\t\treturn r, err\n\t\t}\n\t}\n\tSetSyncInterval.decodeRequest = func(reader io.Reader) (r SyncIntervalRequest, err error) {\n\t\tfields, err := syncRequestFields(reader, SetSyncInterval.definition.Path)\n\t\tif err == nil {","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/sync.go#L136-L172","documentation":"This is the generic wrapper message from syncRequestFields for all /api/sync/* contract endpoints: 'Parses request [<path>] failed: <detail>'. Any JSON syntax error or type failure while reading the top-level request object ends up here; EOF is first rewritten to 'the request body is empty or truncated (EOF)' and map[string]json.RawMessage is normalized to map[string]interface {} in the detail.","triggerScenarios":"Malformed JSON such as {enabled:} or trailing commas; top-level payload being an array or string instead of an object; wrong Content-Type causing the raw body to be misread; duplicate fields or invalid numeric literals rejected by the legacy parser.","commonSituations":"Hand-written payloads with unquoted keys; clients sending form-encoded data to a JSON endpoint; template engines interpolating invalid JSON; version mismatch where an old field format no longer parses.","solutions":["Read the detail after 'failed: ' — it names the exact JSON problem","Validate the JSON with a parser/linter before sending","Ensure the top level is a JSON object containing the endpoint's expected fields (enabled, interval, mode, provider, name, etc.)"],"exampleFix":"// before\n{\"enabled\": true,}   // trailing comma -> parse error\n// after\n{\"enabled\": true}","handlingStrategy":"validation","validationCode":"try { JSON.stringify(payload); } catch (e) { throw new Error('payload is not valid JSON: ' + e.message); }","typeGuard":"const isObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);","tryCatchPattern":"const res = await fetchPost(path, payload); if (res.code !== 0 && res.msg.startsWith('Parses request')) { console.error('payload rejected:', res.msg); }","preventionTips":["Validate JSON payloads before sending","Ensure the top level is an object with the endpoint's required fields","Avoid hand-writing JSON — build objects and let the client serialize"],"tags":["http","json","sync","parse-error"],"backgroundTag":"json-parse-error","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"}