{"record":{"id":"7b0afbad14a27a16","repo":"siyuan-note/siyuan","slug":"the-request-body-is-empty-or-truncated-eof-setting-config","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/setting_config.go","lineNumber":31,"sourceCode":"type settingConfig struct {\n\traw         json.RawMessage\n\tfields      map[string]json.RawMessage\n\tconfigError error\n}\n\nfunc (r settingConfig) ConfigJSON() []byte        { return append([]byte(nil), r.raw...) }\nfunc (r settingConfig) ConfigError() error        { return r.configError }\nfunc (r settingConfig) HasField(name string) bool { _, ok := r.fields[name]; return ok }\n\nfunc decodeSettingConfig(reader io.Reader, path string, removeApp bool) (r settingConfig, err error) {\n\tvar raw json.RawMessage\n\terr = json.NewDecoder(reader).Decode(&raw)\n\tif err == nil {\n\t\tr.fields, 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\treturn\n\t}\n\tif removeApp {\n\t\tdelete(r.fields, \"app\")\n\t}\n\tr.raw, err = json.Marshal(r.fields)\n\treturn\n}\n\nfunc settingConfigError(err error) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\tmessage := strings.ReplaceAll(err.Error(), \"apicontract.Setting\", \"conf.\")\n\tmessage = strings.ReplaceAll(message, \"field Setting\", \"field \")","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/setting_config.go#L13-L49","documentation":"decodeSettingConfig decodes the request body of setting-related config endpoints into a JSON object. When json.Decoder returns io.EOF it means the body was empty or cut off mid-stream, and the decoder replaces the bare EOF with this explicit message, then wraps it as 'Parses request [path] failed'.","triggerScenarios":"POSTing to a setting config endpoint (routed through decodeSettingConfig) with no body at all, a zero-length body, or a body truncated before a complete JSON value arrives.","commonSituations":"Fetch/axios calls that omit `body` on POST, proxies or load balancers cutting off large request bodies, clients aborting mid-upload, or tests forgetting to attach a payload.","solutions":["Attach a valid JSON object body to the request","Set Content-Type: application/json and re-send","Check network path (proxy, body size limits) for truncation","Catch the wrapped error and log request body length to confirm emptiness"],"exampleFix":"// before\nawait fetch('/api/setting/setConfig', { method: 'POST' })\n// after\nawait fetch('/api/setting/setConfig', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(config) })","handlingStrategy":"validation","validationCode":"async function postJson(url: string, payload: unknown) {\n  const body = JSON.stringify(payload);\n  if (!body || body === '{}') throw new Error('refusing to send empty body');\n  return fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body });\n}","typeGuard":null,"tryCatchPattern":"try { const res = await api.call(cmd, payload); } catch (e) { if (String(e).includes('empty or truncated (EOF)')) { retryWithBody(cmd, payload); } }","preventionTips":["Always pass a body on POST requests, even {}","Set Content-Type: application/json explicitly","Increase proxy/CDN body timeouts and size limits for large payloads","Confirm no early return/abort before the fetch body is written"],"tags":["http","json","empty-body","eof"],"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"}