siyuan-note/siyuan · error

not a valid workspace

Error message

not a valid workspace: %s

What it means

The workspace directory exists but fails util.IsWorkspaceDir's structural check, so the CLI refuses to initialize it. A valid SiYuan workspace must contain its marker subdirectories/files (e.g. the conf/data layout SiYuan creates); this prevents pointing the kernel at an arbitrary or foreign directory and mutating unrelated data.

Solutions

  1. Point -w (or SIYUAN_WORKSPACE_PATH) at the actual workspace root — the directory SiYuan created (it contains conf/, data/, etc.), not a parent or a data subfolder.
  2. Open the intended directory once in the SiYuan app so it is properly initialized as a workspace, then rerun the CLI.
  3. List the directory contents and confirm the workspace structure; correct the path if you accidentally targeted an empty or unrelated folder.

Example fix

// before: pointing at parent
SiYuan-Kernel search -w ~/Documents
// after: pointing at the workspace root
SiYuan-Kernel search -w ~/SiYuan
Defensive patterns

Strategy: validation

Validate before calling

# Shell: confirm the directory looks like a SiYuan workspace
[ -d "$WS/conf" ] && [ -d "$WS/data" ] || { echo "not a SiYuan workspace: $WS"; exit 1; }

Try / catch

if err := runKernelCLI(args); err != nil && strings.HasPrefix(err.Error(), "not a valid workspace") {
    // open the directory in the SiYuan app once to initialize it, then retry
}

Prevention

When it happens

Trigger: Passing -w or SIYUAN_WORKSPACE_PATH pointing at an existing directory that is not a SiYuan workspace — e.g. an empty folder, a directory containing only notebooks without workspace metadata, or a path that once was a workspace but lost its marker entries.

Common situations: Typo so -w lands on the parent or sibling of the real workspace; pointing at a folder created manually with just docs; pointing at a data/ subfolder instead of the workspace root; partially deleted/restored workspaces missing their marker files.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: 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 9f775e8a12)