siyuan-note/siyuan · error
event.data is required
Error message
event.data is required
What it means
Panicked (converted to a Go error via rt.NewGoError) when the SSE port.send() receives an event object that has no data field (data is undefined). The SSE spec requires a data field for every event, so the kernel treats its absence as a hard error rather than silently dropping the event.
Source
Thrown at kernel/plugin/plugin.go:1384
invokePortHook := func(name string, args ...goja.Value) {
hook := port.Get(name)
if fn, ok := goja.AssertFunction(hook); ok {
if _, callErr := fn(port, args...); callErr != nil {
logging.LogErrorf("[plugin:%s] sse server port hook %q: %v", p.Name, name, callErr)
}
}
}
port_send := rt.ToValue(func(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
if eventJs := call.Argument(0); isJsValueNotNull(eventJs) {
if eventObj := eventJs.ToObject(rt); eventObj != nil {
e := sse.Event{}
if data := eventObj.Get("data"); isJsValueNotUndefined(data) {
e.Data = data.Export()
} else {
panic(rt.NewGoError(fmt.Errorf("event.data is required")))
}
if event := eventObj.Get("event"); goja.IsString(event) {
e.Event = event.String()
}
if id := eventObj.Get("id"); goja.IsString(id) {
e.Id = id.String()
}
if retry := eventObj.Get("retry"); goja.IsNumber(retry) {
e.Retry = uint(retry.ToInteger())
}
events.In <- e
return goja.Undefined()
}
}View on GitHub (pinned to 251596fc0d)
Solutions
- Always include data: port.send({ data: 'hello', event: 'ping' }).
- Default data to an empty string if you genuinely want an empty payload: port.send({ data: '' }).
- Validate the event object shape before calling send.
Example fix
// before
port.send({ event: name });
// after
port.send({ event: name, data: payload ?? '' }); Defensive patterns
Strategy: validation
Validate before calling
function hasData(e: any): boolean { return !!e && typeof e === 'object' && 'data' in e && e.data !== undefined; } Type guard
function isSseEvent(e: unknown): e is { data: unknown; event?: string; id?: string; retry?: number } { return !!e && typeof e === 'object' && 'data' in (e as any) && (e as any).data !== undefined; } Try / catch
try { port.send(event); } catch (e) { if (/event\.data is required/.test(String(e))) { port.send({ ...event, data: '' }); return; } throw e; } Prevention
- Always include a data field on every SSE event.
- Default data to '' when you want an empty payload.
- Validate the event object before send.
When it happens
Trigger: Plugin calls port.send({ event: 'ping' }) or port.send({}) without a data property; or data is set to undefined explicitly.
Common situations: Building an event object conditionally and forgetting to set data on a branch; sending a comment-style event without data.
Related errors
- invalid event object
- handler did not return an object
- invalid response format: %v
- Agent capability name and description are required
- plugin [%s] not found
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/4f7384663d2bb0cc.
Report an issue: GitHub.