siyuan-note/siyuan · error

panic during siyuan.storage.list

Error message

panic during siyuan.storage.list: %v

What it means

The background goroutine that lists the directory for siyuan.storage.list has a deferred recover(); any panic during the listing or the Promise resolve/reject bridge is converted to this error and rejects the Promise. It indicates an unexpected internal crash rather than a caller-visible filesystem problem.

Solutions

  1. Check kernel logs for the panic context and report with the plugin name
  2. Await all storage Promises before unloading/disabling the plugin
  3. Retry the list operation once
  4. Update the kernel and plugin to latest versions
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const entries = await siyuan.storage.list(dir);
} catch (e) {
  if (String(e).includes("panic during")) {
    console.error("kernel-internal panic during list; check kernel logs");
  } else throw e;
}

Prevention

When it happens

Trigger: A runtime panic inside the storage.list goroutine, e.g. while building the result array or while re-entering the goja worker to resolve the Promise. Rare and typically kernel-internal.

Common situations: Plugin/worker being torn down concurrently with an in-flight list; goja runtime bridge faults; kernel bugs.

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


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/9b0f5322ae480126. Report an issue: GitHub.

Appendix: source

Thrown at kernel/plugin/api_storage.go:409

		} else {
			path = call.Argument(0).String()
		}

		runErr := p.worker.Run(func(rt *goja.Runtime) (result any, err error) {
			if argErr != nil {
				err = argErr
				return
			}
			abs, resolveErr := resolvePath(path)
			if resolveErr != nil {
				err = resolveErr
				return
			}

			go func() (result any, err error) {
				defer func() {
					if r := recover(); r != nil {
						err = fmt.Errorf("panic during siyuan.storage.list: %v", r)
					}
					p.worker.Run(func(rt *goja.Runtime) (_ any, _ error) {
						if lo.IsNil(err) {
							if resolveErr := resolve(result); resolveErr != nil {
								logging.LogErrorf("[plugin:%s] siyuan.storage.list resolve: %v", p.Name, resolveErr)
							}
						} else {
							if rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {
								logging.LogErrorf("[plugin:%s] siyuan.storage.list reject: %v", p.Name, rejectErr)
							}
						}
						return
					}, nil)
				}()

				entries, readErr := os.ReadDir(abs)
				if readErr != nil {
					err = fmt.Errorf("failed to read directory: %w", readErr)

View on GitHub (pinned to 9f775e8a12)