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
- Confirm the full path exists in the runtime (check with rt.GlobalObject().Get on each segment)
- Update the plugin or kernel so both sides agree on the API path
- Validate dispatch/request paths against the known siyuan API surface before resolving
- 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
- Keep kernel and plugin API surface versions aligned
- Validate dispatch/request paths against known API names
- Treat undefined paths as optional features and degrade gracefully
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
- path : expected object, got %T
- path : value is nil
- expected promise object, got %T
- failed to enable extend modules
- failed to inject global context
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)