siyuan-note/siyuan · error
the request body is empty or truncated (EOF)
Error message
the request body is empty or truncated (EOF)
What it means
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'.
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
Example fix
// before
await fetch('/api/setting/setConfig', { method: 'POST' })
// after
await fetch('/api/setting/setConfig', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(config) }) Defensive patterns
Strategy: validation
Validate before calling
async function postJson(url: string, payload: unknown) {
const body = JSON.stringify(payload);
if (!body || body === '{}') throw new Error('refusing to send empty body');
return fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body });
} Try / catch
try { const res = await api.call(cmd, payload); } catch (e) { if (String(e).includes('empty or truncated (EOF)')) { retryWithBody(cmd, payload); } } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- the request body is empty or truncated (EOF)
- the request body is empty or truncated (EOF)
- map[string]json.RawMessage
- Parses request [ ] failed
- Parses request [ ] failed
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/7b0afbad14a27a16.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/setting_config.go:31
type settingConfig struct {
raw json.RawMessage
fields map[string]json.RawMessage
configError error
}
func (r settingConfig) ConfigJSON() []byte { return append([]byte(nil), r.raw...) }
func (r settingConfig) ConfigError() error { return r.configError }
func (r settingConfig) HasField(name string) bool { _, ok := r.fields[name]; return ok }
func decodeSettingConfig(reader io.Reader, path string, removeApp bool) (r settingConfig, err error) {
var raw json.RawMessage
err = json.NewDecoder(reader).Decode(&raw)
if err == nil {
r.fields, err = legacyJSONValue[map[string]json.RawMessage](raw)
}
if err != nil {
if errors.Is(err, io.EOF) {
err = errors.New("the request body is empty or truncated (EOF)")
}
detail := strings.ReplaceAll(err.Error(), "map[string]json.RawMessage", "map[string]interface {}")
err = fmt.Errorf("Parses request [%s] failed: %s", path, detail)
return
}
if removeApp {
delete(r.fields, "app")
}
r.raw, err = json.Marshal(r.fields)
return
}
func settingConfigError(err error) error {
if err == nil {
return nil
}
message := strings.ReplaceAll(err.Error(), "apicontract.Setting", "conf.")
message = strings.ReplaceAll(message, "field Setting", "field ")View on GitHub (pinned to 9f775e8a12)