{"record":{"id":"ee1f5ef2b575cd2a","repo":"siyuan-note/siyuan","slug":"second-argument-must-be-a-config-object","errorCode":null,"errorMessage":"second argument must be a config object","messagePattern":"second argument must be a config object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_agent.go","lineNumber":125,"sourceCode":"\t\t\t\t\t\t}\n\t\t\t\t\t\tif outputSchemaValue := configObj.Get(\"outputSchema\"); isJsValueNotNull(outputSchemaValue) {\n\t\t\t\t\t\t\tif outputSchema, err = jsCapabilitySchemaToGoSchema(rt, outputSchemaValue); err != nil {\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif effectsValue := configObj.Get(\"effects\"); isJsValueNotNull(effectsValue) {\n\t\t\t\t\t\t\tif effects, err = jsCapabilityEffectsToGoEffects(rt, effectsValue); err != nil {\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif actionEffectsValue := configObj.Get(\"actionEffects\"); isJsValueNotNull(actionEffectsValue) {\n\t\t\t\t\t\t\tif actionEffects, err = jsCapabilityActionEffectsToGoEffects(rt, actionEffectsValue); err != nil {\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\terr = fmt.Errorf(\"second argument must be a config object\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif fn, ok := goja.AssertFunction(call.Argument(2)); ok {\n\t\t\t\t\thandler = fn\n\t\t\t\t} else {\n\t\t\t\t\terr = fmt.Errorf(\"third argument must be a handler function\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\treturn\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 {\n\t\t\t\terr = argErr\n\t\t\t\treturn\n\t\t\t}\n","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/plugin/api_agent.go#L107-L143","documentation":"Thrown by siyuan.agent.registerCapability when the second argument (config) fails isJsValueNotNull — meaning it is null, undefined, or goja's representation of absent. The function needs a config object to extract description, inputSchema, and optional fields; a null config makes all of those inaccessible.","triggerScenarios":"Calling registerCapability('myTool', null, handler), registerCapability('myTool', undefined, handler), or omitting the second argument entirely so goja pads it with undefined.","commonSituations":"Plugin builds the config object conditionally and it ends up null; the config variable was declared but never assigned; a refactor moved config construction into a function that returns null on some path.","solutions":["Pass a non-null config object with at minimum description and inputSchema fields","If config is built dynamically, add a null check before calling registerCapability"],"exampleFix":"// before\nawait siyuan.agent.registerCapability('myTool', null, handler);\n\n// after\nawait siyuan.agent.registerCapability('myTool', {\n  description: 'My tool',\n  inputSchema: { type: 'object', properties: {} }\n}, handler);","handlingStrategy":"validation","validationCode":"if (config == null || typeof config !== 'object') {\n  throw new Error('Config must be a non-null object');\n}\nawait siyuan.agent.registerCapability(name, config, handler);","typeGuard":"function isNonNullObject(v) {\n  return v !== null && v !== undefined && typeof v === 'object';\n}","tryCatchPattern":null,"preventionTips":["Construct the config object explicitly before calling registerCapability","Add a null check if the config is built conditionally"],"tags":["plugin","agent","capability","validation","javascript"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}