siyuan-note/siyuan · error

invalid jsonrpc version

Error message

invalid jsonrpc version: %s

What it means

JsonRpcRequest.UnmarshalJSON requires the jsonrpc member to equal the supported JsonRpcVersion ("2.0"). When the field is present but holds any other value, unmarshalling fails with 'invalid jsonrpc version: %s' including the received value. This rejects JSON-RPC 1.x messages and typo'd version strings.

Solutions

  1. Set the field to the exact string "jsonrpc": "2.0" (no spaces, no suffix)
  2. Ensure the value is serialized as a string, not the number 2.0
  3. Check the client library's protocol version setting and switch it to 2.0
  4. Read the reported version value in the error message to see exactly what was received

Example fix

// before
{"jsonrpc": 2.0, "method": "ping", "id": 1}
// after
{"jsonrpc": "2.0", "method": "ping", "id": 1}
Defensive patterns

Strategy: validation

Validate before calling

if (body.jsonrpc !== "2.0") throw new Error(`jsonrpc must be exactly "2.0", got ${JSON.stringify(body.jsonrpc)}`);

Type guard

const isJsonRpc2 = (body) => body && typeof body.jsonrpc === "string" && body.jsonrpc === "2.0";

Try / catch

try { return await rpcSend(payload); } catch (e) { if (String(e).startsWith("invalid jsonrpc version")) { payload.jsonrpc = "2.0"; return rpcSend(payload); } throw e; }

Prevention

When it happens

Trigger: Sending "jsonrpc":"1.0", "jsonrpc":"2.0-rc", "jsonrpc":"JSON-RPC 2.0", or a numeric jsonrpc: 2.0 (which decodes to "2.0"? no — as string field it errors on decode/type); any non-exact "2.0" string.

Common situations: Clients written against JSON-RPC 1.1/1.0; copy-pasted payloads with quoted or decorated version strings; serializers emitting numeric 2.0 instead of the string "2.0".

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


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/8870a8f7fdf37128. Report an issue: GitHub.

Appendix: source

Thrown at kernel/plugin/rpc.go:116

	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")
	}

	r.JsonRpc = request.JsonRpc.Value
	r.Method = request.Method.Value

View on GitHub (pinned to 9f775e8a12)