{"record":{"id":"8c4d6baa56d24efa","repo":"siyuan-note/siyuan","slug":"the-request-body-is-empty-or-truncated-eof-filetree-input","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/filetree_input.go","lineNumber":23,"sourceCode":"\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"strings\"\n)\n\ntype fileTreeFields map[string]json.RawMessage\n\nfunc fileTreeRequestFields(reader io.Reader, path string) (fields fileTreeFields, err error) {\n\tvar raw json.RawMessage\n\terr = json.NewDecoder(reader).Decode(&raw)\n\tif err == nil {\n\t\tfields, err = legacyJSONValue[fileTreeFields](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(), \"apicontract.fileTreeFields\", \"map[string]interface {}\")\n\t\terr = fmt.Errorf(\"Parses request [%s] failed: %s\", path, detail)\n\t}\n\treturn\n}\n\nfunc fileTreeJSONDecoder[Request, Data any](endpoint *Endpoint[Request, Data]) {\n\tendpoint.decodeRequest = func(reader io.Reader) (request Request, err error) {\n\t\tfields, err := fileTreeRequestFields(reader, endpoint.definition.Path)\n\t\tif err == nil {\n\t\t\trequest, err = fileTreeBind[Request](fields)\n\t\t}\n\t\treturn request, err\n\t}\n}\n\nfunc (r FileTreePathRequest) PathError() error { return r.pathError }","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/filetree_input.go#L5-L41","documentation":"fileTreeRequestFields decodes the request body of a filetree API endpoint with json.Decoder.Decode. When decoding returns io.EOF it means the HTTP body was absent or cut off before any complete JSON value was read, so the library raises this explicit message instead of a bare EOF. It wraps the result into 'Parses request [%s] failed: ...' for the endpoint path.","triggerScenarios":"POSTing to any /api/filetree/* contract endpoint with an empty body, a Content-Length shorter than the actual body, or a connection closed mid-body (truncated transfer).","commonSituations":"fetchPost called with undefined/omitted payload; proxies or gateways truncating bodies; a client forgetting to set the request body on a POST; network interruptions during large uploads.","solutions":["Send a valid JSON object as the request body, e.g. {\"id\":\"...\"} instead of an empty body","Verify the HTTP client actually serializes the payload (check fetchPost second argument is an object, not undefined)","Log the raw body length before sending and compare with Content-Length to find truncation","Check proxies/gateways for body size limits or buffering issues"],"exampleFix":"// before\nfetchPost(\"/api/filetree/removeDoc\", undefined);\n// after\nfetchPost(\"/api/filetree/removeDoc\", { id: \"20240101120000-abcdefg\" });","handlingStrategy":"validation","validationCode":"const body = JSON.stringify(payload ?? {});\nif (body.length <= 2) throw new Error(\"request payload must be a non-empty JSON object\");","typeGuard":"const hasBody = (p) => p !== null && p !== undefined && typeof p === \"object\" && Object.keys(p).length > 0;","tryCatchPattern":"try {\n  const res = await fetchPost(path, payload);\n} catch (e) {\n  if (String(e.message).includes(\"empty or truncated (EOF)\")) {\n    // resend with a valid JSON object body\n  }\n}","preventionTips":["Always pass an object as the payload to fetchPost for POST endpoints","Verify Content-Length matches the serialized body when using custom HTTP clients","Check proxies for body truncation when requests are large"],"tags":["http","json","request-body"],"backgroundTag":"empty-request-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"}