siyuan-note/siyuan · error

panic during siyuan.storage.list: %v

Error message

panic during siyuan.storage.list: %v

What it means

A safety net that converts an unexpected panic inside the siyuan.storage.list goroutine into a Promise rejection. The deferred recover() catches any panic (nil deref, slice OOB, etc.) and formats it. In normal operation it should never trigger; it indicates a bug in the kernel's list path or a corrupted directory entry.

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 251596fc0d)

Solutions

  1. Report the panic value and plugin name to the SiYuan issue tracker with the storage path that triggered it.
  2. Wrap your list call in try/catch and fall back to a cached/empty result.
  3. Reproduce with the latest kernel version to see if the panic is already fixed.
  4. Inspect the kernel log for the matching siyuan.storage.list reject line for the panic detail.

Example fix

// before
const entries = await siyuan.storage.list(dir);

// after
let entries;
try {
  entries = await siyuan.storage.list(dir);
} catch (e) {
  console.error('storage.list panicked, using fallback', e);
  entries = [];
}
Defensive patterns

Strategy: fallback

Try / catch

try { return await siyuan.storage.list(dir); } catch (e) { console.error('storage.list unrecoverable', e); return []; }

Prevention

When it happens

Trigger: A panic occurs after os.ReadDir or while building the results slice, e.g. entry.Info() returning something that breaks a later assumption, or memory corruption in the goja runtime bridging.

Common situations: Encountered alongside a kernel bug report; not something plugin code produces by design. Rare and indicates a bug in SiYuan itself.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/9b0f5322ae480126. Report an issue: GitHub.