{"record":{"id":"763f0b47eeb1a9fd","repo":"siyuan-note/siyuan","slug":"the-request-body-is-empty-or-truncated-eof-sync","errorCode":null,"errorMessage":"the request body is empty or truncated (EOF)","messagePattern":"the request body is empty or truncated \\(EOF\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/sync.go","lineNumber":151,"sourceCode":"\nfunc syncConfigError(err error, name string) error {\n\tif err == nil {\n\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}","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/sync.go#L133-L169","documentation":"syncRequestFields parses the whole body of sync-related endpoints (/api/sync/setSyncEnable, setSyncMode, setSyncProvider, setCloudSyncDir, performSync, etc.). If the JSON decoder hits io.EOF — meaning the request body is completely empty or was cut off mid-stream — it is replaced with this explicit message before being wrapped in 'Parses request [...] failed'.","triggerScenarios":"POSTing to any of the /api/sync/* contract endpoints with no body, a Content-Length of 0, or a truncated/chunked stream; sending a body that is only whitespace; a proxy dropping the body.","commonSituations":"curl -X POST without -d; a fetch() call forgetting the body argument; network interruption between client and kernel truncating the body; misconfigured reverse proxy buffering.","solutions":["Send a valid JSON object body, e.g. {\"enabled\":true} for /api/sync/setSyncEnable","Add Content-Type: application/json and verify Content-Length matches the body","Check client code that the body variable is actually passed and not undefined/null"],"exampleFix":"// before\ncurl -X POST http://127.0.0.1:6806/api/sync/setSyncEnable -H 'Authorization: Token xxx'\n// after\ncurl -X POST http://127.0.0.1:6806/api/sync/setSyncEnable -H 'Authorization: Token xxx' -H 'Content-Type: application/json' -d '{\"enabled\":true}'","handlingStrategy":"validation","validationCode":"if (!body || typeof body !== 'object') throw new Error('sync request body required');","typeGuard":"null","tryCatchPattern":"try { const res = await fetchPost(path, payload); } catch (e) { if (e.msg && e.msg.includes('empty or truncated')) fixRequestBody(); }","preventionTips":["Always pass a JSON body object to sync endpoints","Set Content-Type: application/json","Check Content-Length when behind a proxy"],"tags":["http","json","sync","empty-body"],"backgroundTag":"empty-response-body","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"}