siyuan-note/siyuan · error
Parses request [ ] failed
Error message
Parses request [%s] failed: %s
What it means
Generic request parse failure for all endpoints that decode their body into a field map via blockRequestFields. The message embeds the API path (%s) and the underlying json error, e.g. 'Parses request [/api/block/checkBlockRef] failed: invalid character ...'. It means the body was readable but is not valid JSON or not a JSON object.
Solutions
- Validate the body with a JSON parser before sending and fix syntax errors.
- Use Content-Type: application/json and a real serializer instead of string concatenation.
- Read the embedded json error after 'failed:' — it pinpoints the exact character/offset.
- Compare against a known-good request example from the API docs.
Example fix
// before
{"id": "x",} // trailing comma
// after
{"id": "x"} Defensive patterns
Strategy: validation
Validate before calling
try { JSON.parse(bodyString); } catch (e) { throw new Error("request body is not valid JSON: " + e.message); } Try / catch
try {
await post(path, body);
} catch (e) {
if (String(e.message).startsWith("Parses request")) {
// embedded json error after 'failed:' names the bad character/offset
console.error("Malformed JSON for", path, bodyString);
} else { throw e; }
} Prevention
- Use JSON.stringify exclusively; never concatenate payload strings
- Interpolate values safely (watch quotes and unescaped chars)
- Send Content-Type: application/json
- Lint request fixtures used in tests
When it happens
Trigger: POSTing malformed JSON (trailing commas, single quotes, unquoted keys, concatenated objects) to any blockRequestFields-backed endpoint such as /api/block/checkBlockRef, heading-level transactions, bazaar, or AV requests.
Common situations: Hand-built payload strings with syntax errors, templates/interpolation injecting raw values, text/plain or form-encoded bodies sent to a JSON endpoint, or a proxy rewriting the body.
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
- Parses request [ ] failed: map[string]json.RawMessage
- the request body is empty or truncated (EOF)
- asset path [ ] does not match data path [ ]
- box and dataPath cannot be used together
- element [ ]
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/f80535c823dae2aa.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/block_remaining.go:61
// 特殊解码仅保留这些入口的条件参数和结构体绑定语义,响应仍受各自的契约约束。
func init() {
CheckBlockRef.decodeRequest = decodeCheckBlockRef
GetHeadingLevelTransaction.decodeRequest = decodeHeadingLevel
GetDocHeadingLevelTransaction.decodeRequest = func(reader io.Reader) (request DocHeadingLevelRequest, err error) {
if json.NewDecoder(reader).Decode(&request) != nil {
err = errors.New("invalid heading conversion parameters")
}
return
}
}
func blockRequestFields(reader io.Reader, path string) (fields map[string]json.RawMessage, err error) {
err = json.NewDecoder(reader).Decode(&fields)
if err != nil {
if errors.Is(err, io.EOF) {
err = errors.New("the request body is empty or truncated (EOF)")
}
err = fmt.Errorf("Parses request [%s] failed: %s", path, err)
}
return
}
func decodeCheckBlockRef(reader io.Reader) (request CheckBlockRefRequest, err error) {
fields, err := blockRequestFields(reader, "/api/block/checkBlockRef")
if err != nil {
return request, err
}
if raw, present := fields["scope"]; present {
if bytes.Equal(raw, []byte("null")) || json.Unmarshal(raw, &request.Scope) != nil {
return request, errors.New("Field [scope] should be of type [String]")
}
}
if strings.TrimSpace(request.Scope) == "" {
request.Scope = "blocks"
}
readArray := func(key string, required, nonempty bool) ([]string, error) {View on GitHub (pinned to 9f775e8a12)