siyuan-note/siyuan · error
first argument must be method name string
Error message
first argument must be method name string
What it means
siyuan.rpc.bind validates argument types: the first argument must be a string method name (and, next, the second must be a function). When the first argument is not a string, the call is rejected with this error. The follow-on check for the second argument produces 'second argument must be a function'.
Solutions
- Pass the method name as a plain string: bind('myMethod', fn)
- Reorder arguments if name and handler were swapped
- Convert a non-string name with String(name) only if it is genuinely a name value
- Check the upstream variable producing the name for unexpected types
Example fix
// before
siyuan.rpc.bind({name: 'myMethod'}, handler);
// after
siyuan.rpc.bind('myMethod', handler); Defensive patterns
Strategy: type-guard
Validate before calling
function bindRpc(name, handler, ...descs) {
if (typeof name !== 'string') {
throw new TypeError('rpc.bind first argument must be a method name string');
}
if (typeof handler !== 'function') {
throw new TypeError('rpc.bind second argument must be a function');
}
return siyuan.rpc.bind(name, handler, ...descs);
} Type guard
function isRpcName(v) {
return typeof v === 'string' && v.length > 0;
} Try / catch
try {
siyuan.rpc.bind(name, handler);
} catch (e) {
if (String(e.message).includes('first argument must be method name string')) {
console.error('rpc.bind name must be a string, got:', typeof name, name);
}
throw e;
} Prevention
- Never pass config objects to rpc.bind; use a plain string name
- Keep the (name, handler, ...descriptions) argument order
- Stringify name-like values explicitly at the call boundary if they come from external data
When it happens
Trigger: Calling rpc.bind({name: 'x'}, fn), rpc.bind(fn, fn), or rpc.bind(123, fn) — any non-string first argument.
Common situations: Passing a config object as the first argument assuming an object-based API; swapping argument order; passing a Symbol/enum-like name value instead of a string.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- method name and function required
- attr must be a string or null (got %T)
- block [ ] type is locked: expected , got
- cannot remove storage root
- config.actionEffects contains an empty action
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/735951fa6c77a0bf.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/api_rpc.go:54
rpc := rt.NewObject()
lo.Must0(rpc.Set("bind", rt.ToValue(func(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
promise, resolve, reject := rt.NewPromise()
var argErr error
var name string
var method goja.Callable
var descriptions []string
if len(call.Arguments) < 2 {
argErr = fmt.Errorf("method name and function required")
} else {
nameArg := call.Argument(0)
methodArg := call.Argument(1)
descArgs := call.Arguments[2:]
if goja.IsString(nameArg) {
name = nameArg.String()
} else {
argErr = fmt.Errorf("first argument must be method name string")
}
if argErr == nil {
if methodJs, ok := goja.AssertFunction(methodArg); ok {
method = methodJs
} else {
argErr = fmt.Errorf("second argument must be a function")
}
}
if argErr == nil {
descriptions = make([]string, len(descArgs))
for i, a := range descArgs {
descriptions[i] = a.String()
}
}
}
runErr := p.worker.Run(func(rt *goja.Runtime) (result any, err error) {
if argErr != nil {View on GitHub (pinned to 9f775e8a12)