siyuan-note/siyuan · error
second argument must be a config object
Error message
second argument must be a config object
What it means
The second argument to registerCapability() was not usable as a config object (it was a non-object value such as a string, number, boolean, or null). The runtime calls ToObject on argument 1 and rejects the call when it is not a usable object, because all capability metadata (description, schemas) is read from it.
Solutions
- Pass a plain object literal as the second argument: { description, inputSchema, ... }
- Parse JSON strings into objects before passing (JSON.parse)
- Check that the config variable is defined and typeof === "object"
Example fix
// before
plugin.registerCapability("search", JSON.stringify(config), handler);
// after
plugin.registerCapability("search", config, handler); Defensive patterns
Strategy: type-guard
Validate before calling
if (config === null || typeof config !== "object" || Array.isArray(config)) { throw new TypeError("config must be a plain object"); } Type guard
const isConfigObject = (v) => v != null && typeof v === "object" && !Array.isArray(v);
Try / catch
try { plugin.registerCapability(name, config, handler); } catch (e) { if (String(e).includes("second argument must be a config object")) { throw new TypeError("Pass a plain object as the 2nd argument, not " + typeof config); } throw e; } Prevention
- Pass object literals, not JSON strings — parse JSON first
- Do not pass the handler as the second argument
- Check config-loading code for null results
When it happens
Trigger: registerCapability(name, "description string", handler); registerCapability(name, null, handler); or passing the handler as the second argument with only two arguments total.
Common situations: Passing a JSON string instead of a parsed object; argument order mistakes when the handler is placed second; a config variable that failed to load and is null/undefined.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- first argument must be a tool name string
- third argument must be a handler function
- capability name must not be empty
- config.description is required and must be a string
- config.description must not be empty
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/ee1f5ef2b575cd2a.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/api_agent.go:125
}
if outputSchemaValue := configObj.Get("outputSchema"); isJsValueNotNull(outputSchemaValue) {
if outputSchema, err = jsCapabilitySchemaToGoSchema(rt, outputSchemaValue); err != nil {
return
}
}
if effectsValue := configObj.Get("effects"); isJsValueNotNull(effectsValue) {
if effects, err = jsCapabilityEffectsToGoEffects(rt, effectsValue); err != nil {
return
}
}
if actionEffectsValue := configObj.Get("actionEffects"); isJsValueNotNull(actionEffectsValue) {
if actionEffects, err = jsCapabilityActionEffectsToGoEffects(rt, actionEffectsValue); err != nil {
return
}
}
}
} else {
err = fmt.Errorf("second argument must be a config object")
return
}
if fn, ok := goja.AssertFunction(call.Argument(2)); ok {
handler = fn
} else {
err = fmt.Errorf("third argument must be a handler function")
return
}
return
}
}()
runErr := p.worker.Run(func(rt *goja.Runtime) (result any, err error) {
if argErr != nil {
err = argErr
return
}
View on GitHub (pinned to 9f775e8a12)