siyuan-note/siyuan · warning

globalThis.siyuan.event is not an object

Error message

globalThis.siyuan.event is not an object

What it means

dispatchEvent calls ToObject on the resolved globalThis.siyuan.event value and throws this error when that conversion returns nil. It is a defensive check: the value survived the nil/undefined/null checks but could not be converted to a goja object, so the event handler cannot be looked up.

Source

Thrown at kernel/plugin/sandbox.go:347

		}
	}()

	event, err := getJsContextValue(rt, []any{"siyuan", "event"})
	if err != nil {
		return
	}
	if event == nil {
		err = fmt.Errorf("globalThis.siyuan.event not found")
		return
	}
	if goja.IsUndefined(event) || goja.IsNull(event) {
		err = fmt.Errorf("globalThis.siyuan.event is %s", event.String())
		return
	}

	eventObj := event.ToObject(rt)
	if eventObj == nil {
		err = fmt.Errorf("globalThis.siyuan.event is not an object")
		return
	}

	handlerValue := eventObj.Get("handler")
	handler, ok := goja.AssertFunction(handlerValue)
	if !ok {
		return
	}

	eventJs := rt.ToValue(e)
	invokeResult, invokeErr := handler(event, eventJs)
	if invokeErr != nil {
		err = invokeErr
		return
	}

	async = isJsPromise(invokeResult)
	return

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Inspect what is assigned to globalThis.siyuan.event and replace it with a plain JS object exposing a handler/on function
  2. When bridging Go values into the plugin runtime, wrap them with rt.ToValue / rt.NewObject instead of assigning raw host values
  3. Add a startup assertion in the plugin: if (typeof siyuan.event !== 'object') throw new Error('invalid siyuan.event')

Example fix

// before
siyuan.event = hostBridgeValue; // raw Go-backed value
// after
siyuan.event = { on: (name, cb) => hostBridgeSubscribe(name, cb) };
Defensive patterns

Strategy: type-guard

Validate before calling

if (!siyuan.event || typeof siyuan.event !== 'object' || typeof siyuan.event.on !== 'function') { throw new Error('siyuan.event must be a plain object with an on function'); }

Type guard

const isEventObject = (v) => v != null && typeof v === 'object' && !Array.isArray(v);

Try / catch

if err := dispatchEvent(p, rt, e); err != nil { if strings.Contains(err.Error(), "not an object") { log.Errorf("plugin %s: bad siyuan.event value", p.Name) } return }

Prevention

When it happens

Trigger: globalThis.siyuan.event holds a non-object that defeats ToObject in this goja version — practically only reachable via unusual host values or exotic wrapped values assigned to siyuan.event.

Common situations: Plugin code assigning a host-provided non-JS value (e.g. a Go value bridged without conversion) to siyuan.event; goja version-specific export/bridge quirks.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/589fe95c958caf6c. Report an issue: GitHub.