siyuan-note/siyuan · error
task executor panicked: %v
Error message
task executor panicked: %v
What it means
Worker.Run wraps task execution on the JS event loop with a recover() so a panic inside a TaskExecutor doesn't crash the kernel. When a panic is caught, the original stack is logged and the task fails with this wrapped error, which is then delivered to the TaskCallback. The message includes the panic value; the real stack is in the kernel log.
Source
Thrown at kernel/plugin/worker.go:64
return fmt.Errorf("worker event loop not initialized")
}
success := w.loop.RunOnLoop(func(rt *goja.Runtime) {
var result any
var err error
defer func() {
defer func() {
// 捕获回调中的 panic 并保留原始调用栈,便于定位 Promise 处理异常。
if r := recover(); r != nil {
logging.LogErrorf("task callback panicked: %v\n%s", r, debug.Stack())
}
}()
// 捕获执行器中的 panic 并保留原始调用栈,同时将错误传给回调。
if r := recover(); r != nil {
logging.LogErrorf("task executor panicked: %v\n%s", r, debug.Stack())
err = fmt.Errorf("task executor panicked: %v", r)
}
if callback != nil {
callback(rt, result, err)
}
}()
result, err = executor(rt)
})
if !success {
return fmt.Errorf("failed to run task on event loop")
}
return nil
}
func (w *Worker) RunSync(fn TaskExecutor) (result any, err error) {
response := make(chan TaskResult, 1)
err = w.Run(fn, func(rt *goja.Runtime, result any, err error) {
response <- TaskResult{result, err}View on GitHub (pinned to 8641553a1f)
Solutions
- Read the full stack trace logged by logging.LogErrorf alongside 'task executor panicked' to locate the panicking line.
- Fix the underlying panic in the TaskExecutor (nil check, safe type assertion with ok, bounds check).
- Handle the error in the TaskCallback so callers receive a proper failure instead of hanging.
- Replace unchecked type assertions in the executor with the comma-ok form to convert panics into errors.
Example fix
// before
v := arg.(*MyType)
// after
v, ok := arg.(*MyType)
if !ok {
err = fmt.Errorf("unexpected argument type %T", arg)
return
} Defensive patterns
Strategy: try-catch
Try / catch
func(rt *goja.Runtime) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("task executor panicked: %v", r)
}
}()
// executor body
} Prevention
- Use comma-ok type assertions instead of unchecked assertions in executors.
- Nil-check maps/slices/pointers before use inside task executors.
- Always implement TaskCallback error handling so panics surface to callers.
- Keep the kernel log nearby — the full stack is logged, not returned.
When it happens
Trigger: Any TaskExecutor passed to worker.Run panics — e.g. nil pointer dereference, index out of range, or a type assertion failure while building JS arguments or processing results on the goja runtime.
Common situations: A plugin returns data in an unexpected shape and the executor's type assertion (`x.(*SomeType)`) panics; a nil map/slice access in the executor; a bug introduced by a kernel update in argument conversion code.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- import from local path failed, please check kernel log for d
- injectClient: %v
- injectEvent: %v
- injectLogger: %v
- injectServer: %v
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/b40fc382cdb01412.
Report an issue: GitHub.