siyuan-note/siyuan · error

globalThis.siyuan.event not found

Error message

globalThis.siyuan.event not found

What it means

After resolving the path globalThis.siyuan.event via getJsContextValue, dispatchEvent checks whether the returned value is nil and throws this error if the property lookup yielded nothing. It means the plugin runtime does not expose a siyuan.event object at all, so kernel events cannot be delivered to the plugin.

Source

Thrown at kernel/plugin/sandbox.go:337

	}
	value = cursor
	return
}

// dispatchEvent calls the globalThis.siyuan.event.on hook with the given event object.
func dispatchEvent(p *KernelPlugin, rt *goja.Runtime, e any) (async bool, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("goja panic during dispatchEvent: %v", r)
		}
	}()

	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
	}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Ensure the plugin initializes globalThis.siyuan.event (with an on/addListener hook) during load, before any kernel event can fire
  2. Rebuild/reinstall the plugin against the current SiYuan plugin API so the event shim is created by the runtime bootstrap
  3. Check that the plugin's entry script completed without an earlier error that aborted siyuan initialization

Example fix

// before (plugin JS): no event object created
// after
window.siyuan = window.siyuan || {};
siyuan.event = siyuan.event || { on: (name, cb) => { listeners[name] = cb; } };
Defensive patterns

Strategy: validation

Validate before calling

if (typeof siyuan === 'undefined' || !siyuan.event || typeof siyuan.event.on !== 'function') { throw new Error('plugin must initialize siyuan.event.on before use'); }

Type guard

const eventReady = (g) => g != null && g.siyuan != null && g.siyuan.event != null && typeof g.siyuan.event.on === 'function';

Try / catch

if err := dispatchEvent(p, rt, e); err != nil { if strings.Contains(err.Error(), "not found") { log.Warnf("plugin %s has no event hook: %v", p.Name, err) } return }

Prevention

When it happens

Trigger: The plugin JS context has no siyuan.event defined — the plugin bundle did not initialize the SiYuan plugin API shims, or the property was deleted/never assigned before the kernel dispatches an event.

Common situations: A plugin built against an older plugin API that predates the event bus; a plugin whose entry script failed partway, leaving siyuan partially initialized; manual manipulation of globalThis.siyuan in plugin code.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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