siyuan-note/siyuan · critical

not a valid workspace: %s

Error message

not a valid workspace: %s

What it means

Thrown in `rootCmd.PersistentPreRunE` when the workspace directory exists on disk but fails `util.IsWorkspaceDir(workspacePath)`. SiYuan requires a workspace to look like a valid data root (it must be a writable directory that is not a system/temp/network path and not the user's home root). This guard prevents the kernel from initializing databases and indexes against an unsuitable directory that could corrupt data or hang on special filesystems.

Source

Thrown at kernel/cli/cmd/root.go:90

		langsDir := filepath.Join(util.WorkingDir, "appearance", "langs")
		if _, err := os.Stat(langsDir); os.IsNotExist(err) {
			return fmt.Errorf("appearance files not found at [%s]", langsDir)
		}

		// 设置工作空间路径
		if workspacePath == "" {
			workspacePath = os.Getenv("SIYUAN_WORKSPACE_PATH")
		}
		if workspacePath == "" {
			workspacePath = filepath.Join(util.HomeDir, "SiYuan")
		}

		if _, err := os.Stat(workspacePath); os.IsNotExist(err) {
			return fmt.Errorf("directory not found: %s", workspacePath)
		}
		if !util.IsWorkspaceDir(workspacePath) {
			return fmt.Errorf("not a valid workspace: %s", workspacePath)
		}

		util.Mode = "prod"
		util.InitWorkspace(workspacePath, util.WorkingDir)

		logging.SetLogPath(filepath.Join(util.TempDir, "siyuan-cli.log"))
		logging.SetLogToStdout(false)

		// CLI 单次命令默认 warn 级别(siyuan-cli.log 只保留警告及以上),避免内核初始化的大量 Info/Debug 日志噪声;
		// 用户可通过 --log-level 显式覆盖。把级别记入 util.CLILogLevel,使随后的 model.InitConf 不再用 conf.json 覆盖。
		// 注意 serve 子命令走自己的 PersistentPreRunE,不受此默认值影响,仍跟随 conf.json 的 system.logLevel。
		effectiveLevel := logLevel
		if "" == effectiveLevel {
			effectiveLevel = "warn"
		}
		logging.SetLogLevel(effectiveLevel)
		util.CLILogLevel = effectiveLevel

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Use a dedicated SiYuan workspace directory (the default `~/SiYuan` or a fresh empty dir).
  2. Check `util.IsWorkspaceDir` criteria — avoid home root, temp dirs, and network mounts.
  3. Remove stale lock files if a previous process crashed, then retry.
  4. If upgrading across major versions, let the GUI app migrate the workspace once before using the CLI.

Example fix

// before
siyuan --workspace ~ search foo
// after
siyuan --workspace ~/SiYuan search foo
Defensive patterns

Strategy: validation

Validate before calling

// Beyond existence, ensure the dir is a valid SiYuan workspace.
if !util.IsWorkspaceDir(workspacePath) {
    log.Fatalf("not a valid SiYuan workspace: %s", workspacePath)
}

Prevention

When it happens

Trigger: Pointing `--workspace` at `~`, `/tmp`, a network mount root, a non-directory path, or a directory already locked/used by another process; pointing at a folder that lacks the expected SiYuan data layout markers.

Common situations: Setting `--workspace ~` by mistake; sharing a workspace over a network filesystem that `IsWorkspaceDir` rejects; pointing at a folder from a different/older SiYuan version whose layout no longer validates; a leftover `.siyuan` lock from a crashed process.

Related errors


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