{"record":{"id":"ae388d4be596cc04","repo":"siyuan-note/siyuan","slug":"topic-and-event-required","errorCode":null,"errorMessage":"topic and event required","messagePattern":"topic and event required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_event.go","lineNumber":46,"sourceCode":"func injectEvent(p *KernelPlugin, rt *goja.Runtime, siyuan *goja.Object) (err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\terr = fmt.Errorf(\"injectEvent: %v\", r)\n\t\t}\n\t}()\n\n\tevent := rt.NewObject()\n\n\tlo.Must0(event.Set(\"handler\", goja.Null()))\n\n\tlo.Must0(event.Set(\"emit\", 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 topic string\n\t\tvar eventData any\n\t\tif len(call.Arguments) < 2 {\n\t\t\targErr = fmt.Errorf(\"topic and event required\")\n\t\t} else {\n\t\t\ttopic = call.Argument(0).String()\n\t\t\tif topic == \"\" {\n\t\t\t\targErr = fmt.Errorf(\"topic required\")\n\t\t\t} else {\n\t\t\t\teventData = call.Argument(1).Export()\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\t\t\tp.bus.Publish(topic, eventData)\n\t\t\treturn\n\t\t}, func(rt *goja.Runtime, result any, err error) {\n\t\t\tif lo.IsNil(err) {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/api_event.go#L28-L64","documentation":"The siyuan.event emit/publish call requires exactly a topic string and an event payload. When fewer than two arguments are supplied, the call is rejected synchronously and the returned promise rejects with 'topic and event required'. This is strict arity validation before any kernel work is dispatched.","triggerScenarios":"Calling the event function with zero or one argument, e.g. emit('my-topic') with no payload, or emit() with none; spreading an array that has fewer than two elements.","commonSituations":"Assuming an optional/empty default payload; variables named for the payload that ended up undefined and dropped; refactors that removed the data argument but kept the call.","solutions":["Pass both arguments: emit('topic', data)","Pass an explicit empty payload (e.g. {}) when there is no data","Check any spread call emit(...args) actually yields two elements","Verify argument order: topic first, payload second"],"exampleFix":"// before\nawait siyuan.event.publish('my-topic');\n// after\nawait siyuan.event.publish('my-topic', {detail: 'hello'});","handlingStrategy":"validation","validationCode":"function assertPublishArgs(args) {\n  if (!Array.isArray(args) || args.length < 2) {\n    throw new TypeError('publish requires (topic, event) — two arguments');\n  }\n  return args;\n}\n// call site: siyuan.event.publish(...assertPublishArgs([topic, payload]))","typeGuard":"null","tryCatchPattern":"try {\n  await siyuan.event.publish(topic, payload);\n} catch (e) {\n  if (String(e.message).includes('topic and event required')) {\n    console.error('publish called without a payload; topic =', topic);\n  }\n  throw e;\n}","preventionTips":["Always pass an explicit payload, even if it is {}","Wrap publish in a helper that enforces the (topic, event) signature","Avoid naked spread calls with unverified argument arrays"],"tags":["plugin","event","missing-argument","promise"],"backgroundTag":"missing-required-argument","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"}