{"record":{"id":"735951fa6c77a0bf","repo":"siyuan-note/siyuan","slug":"first-argument-must-be-method-name-string","errorCode":null,"errorMessage":"first argument must be method name string","messagePattern":"first argument must be method name string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_rpc.go","lineNumber":54,"sourceCode":"\trpc := rt.NewObject()\n\n\tlo.Must0(rpc.Set(\"bind\", rt.ToValue(func(call goja.FunctionCall, rt *goja.Runtime) goja.Value {\n\t\tpromise, resolve, reject := rt.NewPromise()\n\n\t\tvar argErr error\n\t\tvar name string\n\t\tvar method goja.Callable\n\t\tvar descriptions []string\n\t\tif len(call.Arguments) < 2 {\n\t\t\targErr = fmt.Errorf(\"method name and function required\")\n\t\t} else {\n\t\t\tnameArg := call.Argument(0)\n\t\t\tmethodArg := call.Argument(1)\n\t\t\tdescArgs := call.Arguments[2:]\n\t\t\tif goja.IsString(nameArg) {\n\t\t\t\tname = nameArg.String()\n\t\t\t} else {\n\t\t\t\targErr = fmt.Errorf(\"first argument must be method name string\")\n\t\t\t}\n\t\t\tif argErr == nil {\n\t\t\t\tif methodJs, ok := goja.AssertFunction(methodArg); ok {\n\t\t\t\t\tmethod = methodJs\n\t\t\t\t} else {\n\t\t\t\t\targErr = fmt.Errorf(\"second argument must be a function\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tif argErr == nil {\n\t\t\t\tdescriptions = make([]string, len(descArgs))\n\t\t\t\tfor i, a := range descArgs {\n\t\t\t\t\tdescriptions[i] = a.String()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\trunErr := p.worker.Run(func(rt *goja.Runtime) (result any, err error) {\n\t\t\tif argErr != nil {","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/plugin/api_rpc.go#L36-L72","documentation":"Thrown by siyuan.rpc.bind when the first argument is not a string. The RPC method name must be a string so it can be looked up by callers.","triggerScenarios":"Calling bind(123, fn), bind({name:'x'}, fn), or bind(undefined, fn). goja.IsString(nameArg) is false at api_rpc.go:51.","commonSituations":"Plugin builds the name from a non-string constant, or passes an object expecting destructuring.","solutions":["Pass the method name as a string: siyuan.rpc.bind('add', fn).","Coerce: siyuan.rpc.bind(String(name), fn)."],"exampleFix":"// before\nsiyuan.rpc.bind(methodId, fn);\n// after\nsiyuan.rpc.bind('add', fn);","handlingStrategy":"type-guard","validationCode":"if (typeof name !== 'string') throw new TypeError('name must be string');\nsiyuan.rpc.bind(name, fn);","typeGuard":"const isMethodName = (v) => typeof v === 'string' && v.length > 0;","tryCatchPattern":null,"preventionTips":["Use string constants for RPC method names.","Validate the name type before bind."],"tags":["rpc","bind","validation","type"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}