siyuan-note/siyuan · error

path : value is

Error message

path %v: value is %s

What it means

getJsContextValue traverses a property path from globalThis and rejects undefined/null intermediates because they cannot be dereferenced further. When the cursor at some key is undefined or null, this error reports the key and its string form ("undefined" or "null"). It means the requested path points through a property that does not exist in the runtime's global context.

Solutions

  1. Confirm the full path exists in the runtime (check with rt.GlobalObject().Get on each segment)
  2. Update the plugin or kernel so both sides agree on the API path
  3. Validate dispatch/request paths against the known siyuan API surface before resolving
  4. Treat the error as 'API not present in this runtime' and degrade the caller gracefully

Example fix

// before
getJsContextValue(rt, []any{"siyuan", "rpc", "oldMethod"}) // error: path oldMethod: value is undefined
// after
v, err := getJsContextValue(rt, []any{"siyuan", "rpc", "oldMethod"})
if err != nil {
    logging.LogWarnf("api not available: %v", err)
    return
}
Defensive patterns

Strategy: validation

Validate before calling

v, err := getJsContextValue(rt, paths)
if err != nil || v == nil || goja.IsUndefined(v) || goja.IsNull(v) {
    // API not present in this runtime; degrade
}

Try / catch

v, err := getJsContextValue(rt, paths)
if err != nil {
    logging.LogWarnf("api unavailable: %v", err)
    return
}

Prevention

When it happens

Trigger: Calling getJsContextValue with a path containing a missing property — e.g. obj.Get(k) returned undefined for a key, or a namespace like siyuan.agent was never injected, and a later hop tries to traverse it.

Common situations: Event or request dispatch referencing an API that a plugin version doesn't provide; renamed API endpoints between kernel versions; dynamic path construction from user/plugin input containing invalid segments.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at kernel/plugin/sandbox.go:298

	if err := ObjectSetDataMethods(p, rt, obj, data); err != nil {
		return nil, err
	}
	return obj, nil
}

// getJsContextValue safely retrieves a nested value from the plugin's JS context, returning nil if any step fails.
func getJsContextValue(rt *goja.Runtime, paths []any) (value goja.Value, err error) {
	var cursor goja.Value = rt.GlobalObject()
	var path string = "globalThis"

	for _, key := range paths {
		if cursor == nil {
			err = fmt.Errorf("path %v: value is nil", key)
			return
		}

		if goja.IsUndefined(cursor) || goja.IsNull(cursor) {
			err = fmt.Errorf("path %v: value is %s", key, cursor.String())
			return
		}

		obj := cursor.ToObject(rt)
		if obj == nil {
			err = fmt.Errorf("path %v: expected object, got %T", key, cursor)
			return
		}

		switch k := key.(type) {
		case string:
			cursor = obj.Get(k)
			path = fmt.Sprintf("%s.%s", path, k)
		case int:
			cursor = obj.Get(strconv.Itoa(k))
			path = fmt.Sprintf("%s[%d]", path, k)
		default:
			err = fmt.Errorf("unsupported path type: %T", key)

View on GitHub (pinned to 8641553a1f)