siyuan-note/siyuan · error
missing jsonrpc field
Error message
missing jsonrpc field
What it means
JsonRpcRequest.UnmarshalJSON validates incoming JSON-RPC 2.0 messages before dispatch. The 'jsonrpc' member is mandatory and must be exactly the supported version string; when the raw message lacks the jsonrpc field entirely, unmarshalling fails with 'missing jsonrpc field'. This enforces the JSON-RPC 2.0 spec requirement that every request carry a jsonrpc member.
Solutions
- Add "jsonrpc": "2.0" to every request body
- Verify the exact payload sent with a network capture or by logging the raw body before unmarshal
- If using a client library, configure the JSON-RPC 2.0 mode rather than raw JSON posting
- Retest with a known-good minimal request: {"jsonrpc":"2.0","method":"ping","id":1}
Example fix
// before
{"method": "ping", "id": 1}
// after
{"jsonrpc": "2.0", "method": "ping", "id": 1} Defensive patterns
Strategy: validation
Validate before calling
function buildRpcRequest(method, params, id) { return { jsonrpc: "2.0", method, ...(params !== undefined ? { params } : {}), ...(id !== undefined ? { id } : {}) }; } Type guard
const hasJsonRpcField = (body) => body && typeof body === "object" && typeof body.jsonrpc === "string";
Try / catch
try { return await rpcSend(payload); } catch (e) { if (String(e).includes("missing jsonrpc field")) { console.error("payload sent:", JSON.stringify(payload)); } throw e; } Prevention
- Always include "jsonrpc": "2.0" in every request
- Use a JSON-RPC 2.0 client library or a shared request builder
- Log raw payloads when debugging RPC failures
- Add a payload schema test for your RPC client
When it happens
Trigger: Posting a JSON body to the plugin RPC endpoint without a "jsonrpc" key, e.g. {"method":"x","id":1}; clients built for JSON-RPC 1.0 or ad-hoc protocols omitting the field; hand-crafted curl/test payloads.
Common situations: Developers testing the RPC endpoint with curl or Postman using a minimal body; custom MCP/JSON-RPC clients that forgot the version field; middleware stripping unknown fields from payloads.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- invalid id field: must be string, number, null or omitted
- invalid jsonrpc version
- invalid jsonrpc version
- missing method field
- RPC call requires a request or error
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/ab679e8f81dad770.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/rpc.go:113
}
func (r *JsonRpcRequest) UnmarshalJSON(data []byte) error {
decoder := json.NewDecoder(bytes.NewReader(data))
// decoder.DisallowUnknownFields() // Reject unknown fields violates the JSON-RPC spec
type JsonRpcRequestObject struct {
JsonRpc util.Optional[string] `json:"jsonrpc"`
Method util.Optional[string] `json:"method"`
Params util.Optional[any] `json:"params"`
ID util.Optional[any] `json:"id"`
}
request := JsonRpcRequestObject{}
if err := decoder.Decode(&request); err != nil {
return err
}
// Validate jsonrpc field
if !request.JsonRpc.Exists {
return fmt.Errorf("missing jsonrpc field")
}
if request.JsonRpc.Value != JsonRpcVersion {
return fmt.Errorf("invalid jsonrpc version: %s", request.JsonRpc.Value)
}
// Validate method field
if !request.Method.HasValue() {
return fmt.Errorf("missing method field")
}
// Validate id field
if !request.ID.Exists {
} else if request.ID.IsNull {
} else if _, ok := request.ID.Value.(string); ok {
} else if _, ok := request.ID.Value.(float64); ok {
} else {
return fmt.Errorf("invalid id field: must be string, number, null or omitted")
}View on GitHub (pinned to 9f775e8a12)