siyuan-note/siyuan · error

create plugin dir [%s] failed: %s

Error message

create plugin dir [%s] failed: %s

What it means

At the beginning of plugin startup, the kernel creates the plugin's data directory at `data/storage/petal/<pluginName>` with `os.MkdirAll`. If that fails (permissions, disk full, path occupied by a file), startup aborts with `create plugin dir [<path>] failed: <reason>`. The plugin never reaches runtime initialization.

Source

Thrown at kernel/plugin/plugin.go:270

	p.updateState(PluginStateError)
}

// start creates the goja runtime, injects sandbox globals, and evaluates kernel.js.
func (p *KernelPlugin) start() (err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("goja panic during start: %v", r)
		}
		if err != nil {
			p.error()
		}
	}()

	p.updateState(PluginStateLoading)

	baseDir := filepath.Join(util.DataDir, "storage", "petal", p.Name)
	if err := os.MkdirAll(baseDir, 0755); err != nil {
		return fmt.Errorf("create plugin dir [%s] failed: %s", baseDir, err)
	}

	if runtimeErr := p.InitRuntime(); runtimeErr != nil {
		return fmt.Errorf("start runtime: %v", runtimeErr)
	}

	if subscribeErr := p.subscribeEventHandlers(); subscribeErr != nil {
		return fmt.Errorf("subscribe plugin events: %v", subscribeErr)
	}

	p.onLoad()
	p.updateState(PluginStateRunning)
	p.onRunning()

	p.bus.Publish(EventBusTopicRuntime, createEventMessage("start", nil))

	logging.LogDebugf("[plugin:%s] started", p.Name)
	return

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Check whether a FILE exists at the reported path — remove or rename it so a directory can be created
  2. Verify write permissions on `data/storage/petal/` and that the disk is not full
  3. Ensure the workspace directory is writable by the SiYuan process user
  4. Check the plugin name for illegal path characters; update/uninstall the plugin if so
Defensive patterns

Strategy: validation

Validate before calling

// before starting the plugin, check the path is creatable
if info, err := os.Stat(filepath.Join(util.DataDir, "storage", "petal", name)); err == nil && !info.IsDir() {
    return fmt.Errorf("%s exists as a file; remove it so the plugin dir can be created", name)
}

Try / catch

if err := os.MkdirAll(dir, 0755); err != nil { return fmt.Errorf("check disk space and permissions on %s: %w", dir, err) }

Prevention

When it happens

Trigger: os.MkdirAll failing because a file already exists at the plugin's directory path, the data directory is read-only, disk quota is exhausted, or the plugin name contains characters invalid for the host filesystem.

Common situations: Running SiYuan from a read-only mount or restricted workspace directory, an OS-level file locking the path, a plugin name with `/` or reserved characters creating a bad path, or full disk on mobile devices.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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