siyuan-note/siyuan · error
Parses request [ ] failed
Error message
Parses request [%s] failed: %s
What it means
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.
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.)
Example fix
// before
{"enabled": true,} // trailing comma -> parse error
// after
{"enabled": true} Defensive patterns
Strategy: validation
Validate before calling
try { JSON.stringify(payload); } catch (e) { throw new Error('payload is not valid JSON: ' + e.message); } Type guard
const isObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
Try / catch
const res = await fetchPost(path, payload); if (res.code !== 0 && res.msg.startsWith('Parses request')) { console.error('payload rejected:', res.msg); } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- the request body is empty or truncated (EOF)
- map[string]json.RawMessage
- Parses request [ ] failed
- Parses request [ ] failed
- struct field Sync .
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/535abbb2576bd339.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/sync.go:154
return nil
}
detail := strings.ReplaceAll(err.Error(), "apicontract.Sync"+name, "conf."+name)
return errors.New(strings.ReplaceAll(detail, "struct field Sync"+name+".", "struct field "+name+"."))
}
// syncRequestFields 保留整份请求的 JSON 数字解析、重复字段和首个对象读取语义。
func syncRequestFields(reader io.Reader, path string) (fields map[string]json.RawMessage, err error) {
var raw json.RawMessage
err = json.NewDecoder(reader).Decode(&raw)
if err == nil {
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
}
func init() {
for _, endpoint := range []*Endpoint[SyncEnabledRequest, Null]{&SetSyncEnable, &SetSyncPerception, &SetSyncGenerateConflictDoc} {
path := endpoint.definition.Path
endpoint.decodeRequest = func(reader io.Reader) (r SyncEnabledRequest, err error) {
fields, err := syncRequestFields(reader, path)
if err == nil {
r.Enabled, err = legacyField[bool](fields, "enabled", "Boolean", true)
}
return r, err
}
}
SetSyncInterval.decodeRequest = func(reader io.Reader) (r SyncIntervalRequest, err error) {
fields, err := syncRequestFields(reader, SetSyncInterval.definition.Path)
if err == nil {View on GitHub (pinned to 9f775e8a12)