{"record":{"id":"0532073b55a83671","repo":"siyuan-note/siyuan","slug":"invalid-id-field-must-be-string-number-null-or","errorCode":null,"errorMessage":"invalid id field: must be string, number, null or omitted","messagePattern":"invalid id field: must be string, number, null or omitted","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/rpc.go","lineNumber":130,"sourceCode":"\tif !request.JsonRpc.Exists {\n\t\treturn fmt.Errorf(\"missing jsonrpc field\")\n\t}\n\tif request.JsonRpc.Value != JsonRpcVersion {\n\t\treturn fmt.Errorf(\"invalid jsonrpc version: %s\", request.JsonRpc.Value)\n\t}\n\n\t// Validate method field\n\tif !request.Method.HasValue() {\n\t\treturn fmt.Errorf(\"missing method field\")\n\t}\n\n\t// Validate id field\n\tif !request.ID.Exists {\n\t} else if request.ID.IsNull {\n\t} else if _, ok := request.ID.Value.(string); ok {\n\t} else if _, ok := request.ID.Value.(float64); ok {\n\t} else {\n\t\treturn fmt.Errorf(\"invalid id field: must be string, number, null or omitted\")\n\t}\n\n\tr.JsonRpc = request.JsonRpc.Value\n\tr.Method = request.Method.Value\n\tr.Params = request.Params\n\tr.ID = request.ID\n\treturn nil\n}\n\n// IsNotification returns true if this request is a notification (no ID field).\nfunc (r *JsonRpcRequest) IsNotification() bool {\n\treturn r.ID.Exists == false\n}\n\n// Validate validates the JSON-RPC request structure.\nfunc (r *JsonRpcRequest) Validate() *JsonRpcError {\n\t// params is optional, but if present must be either an array (for positional parameters) or an object (for named parameters)\n\tif !r.Params.Exists {","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/rpc.go#L112-L148","documentation":"JSON-RPC 2.0 restricts the 'id' member to string, number, or null (or the field may be omitted for notifications). JsonRpcRequest.UnmarshalJSON enforces this: if id exists, is not null, and is neither string nor float64, it fails with 'invalid id field: must be string, number, null or omitted'. This keeps correlation IDs spec-compliant so responses can be matched to requests.","triggerScenarios":"Sending \"id\": true/false (boolean), \"id\": {\"n\":1} (object), or \"id\": [1] (array); clients auto-generating UUID objects instead of strings; batching frameworks that inject non-scalar IDs.","commonSituations":"Custom clients using boolean flags as IDs; JavaScript engines passing objects; test scripts with id: true to mean 'request'; serializers that box numbers into objects.","solutions":["Use a string or number for id, or omit it entirely for notifications","Replace boolean/object id values with a generated numeric or string identifier","Validate the payload schema before sending (id must be scalar or null)","Check client library settings for automatic ID generation and force scalar IDs"],"exampleFix":"// before\n{\"jsonrpc\": \"2.0\", \"method\": \"ping\", \"id\": true}\n// after\n{\"jsonrpc\": \"2.0\", \"method\": \"ping\", \"id\": \"req-1\"}","handlingStrategy":"validation","validationCode":"function validId(id) { return id === undefined || id === null || typeof id === \"string\" || typeof id === \"number\"; }","typeGuard":"const isRpcId = (v) => v === undefined || v === null || typeof v === \"string\" || (typeof v === \"number\" && Number.isFinite(v));","tryCatchPattern":"try { return await rpcSend(payload); } catch (e) { if (String(e).includes(\"invalid id field\")) { payload.id = String(payload.id); return rpcSend(payload); } throw e; }","preventionTips":["Restrict ids to strings or finite numbers; never booleans, arrays, or objects","Generate ids via a counter or UUID string","Omit id entirely for notifications instead of sending null-like placeholders","Add a schema check for id in your RPC client's send path"],"tags":["json-rpc","validation","type-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}