siyuan-note/siyuan · error · GoError
invalid event object
Error message
invalid event object
What it means
The SSE port's send function falls through to panic with 'invalid event object' when its first argument is null/undefined or cannot be converted to a JS object. Unlike 'event.data is required' (object present but missing data), this error means send() did not receive a usable object at all.
Solutions
- Always pass a plain object to port.send: port.send({data: ...})
- Guard the call site: if (payload) port.send({data: payload})
- Ensure variables hold the event object, not a resolved inner value that may be undefined
- Wrap sends in try/catch so a transient bad payload does not kill the SSE handler
Example fix
// before
const result = await compute();
port.send(result);
// after
const result = await compute();
if (result != null) { port.send({ data: JSON.stringify(result) }); } Defensive patterns
Strategy: validation
Validate before calling
function assertEventObject(ev) { if (ev === null || ev === undefined || typeof ev !== "object") throw new Error("port.send requires an event object"); } Type guard
const isEventObject = (v) => v !== null && typeof v === "object";
Try / catch
try { port.send(ev); } catch (e) { if (String(e).includes("invalid event object")) { port.send({ data: String(ev) }); } else { throw e; } } Prevention
- Guard possibly-empty async results before passing them to port.send
- Never call port.send with zero arguments, primitives, or null
- Centralize sends in one wrapper that normalizes payloads to {data: ...}
- Test SSE handlers with empty and error results to catch undefined payloads
When it happens
Trigger: Calling port.send() with no arguments; port.send(null) or port.send(undefined); passing a primitive (number/string/boolean) where an event object is expected and ToObject yields nil; passing a value that is not null-checked before ToObject.
Common situations: Async code paths that pass a possibly-empty result variable into port.send; spreading/destructuring mistakes that yield undefined; API misuse after reading examples of the fetch-style API instead of the SSE port API.
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
- event.data is required
- invalid package name
- invalid plugin JSON response
- invalid plugin JSONP response
- invalid plugin secure JSON response
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/4017554ae1d80700.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/plugin.go:1404
}
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()
}
}
panic(rt.NewGoError(fmt.Errorf("invalid event object")))
})
port_close := rt.ToValue(func(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
doClose()
return goja.Undefined()
})
lo.Must0(port.Set("onopen", goja.Null()))
lo.Must0(port.Set("onclose", goja.Null()))
lo.Must0(port.Set("send", port_send))
lo.Must0(port.Set("close", port_close))
lo.Must0(ObjectSeal(rt, port))
lo.Must0(jsRequestObj.Set("port", port))
invokeFunction(func(_ *goja.Runtime, result *CallResult) {View on GitHub (pinned to 9f775e8a12)