siyuan-note/siyuan · error
appearance files not found at
Error message
appearance files not found at [%s]
What it means
The SiYuan CLI kernel binary validates before running any subcommand (except workspace) that an appearance/langs directory exists under the resolved working directory. resolveWorkingDir() probes candidate directories relative to the executable (resources/, app/, macOS bundle Resources) and falls back to util.WorkingDir; if none of them contains appearance/langs, this error aborts the command. It protects UI/i18n-dependent operations from running against an incomplete or mis-deployed installation.
Solutions
- Install the kernel binary in the expected layout so its parent directory contains appearance/langs (production: resources/kernel/SiYuan-Kernel with resources/appearance/).
- Re-download/reinstall the full SiYuan package instead of just the kernel executable.
- Run the binary from a checkout that includes app/appearance/langs (resolveWorkingDir probes kernel/ → app/ and exeDir/app), e.g. build to kernel/ of the repo.
- Verify the path printed in the error actually lacks appearance/langs and create/copy that directory there if it is a custom deployment you control.
Example fix
// before: copying only the binary cp SiYuan-Kernel /opt/siyuan/ // after: keep the resources layout cp -r resources /opt/siyuan/ # contains kernel/SiYuan-Kernel and appearance/langs
Defensive patterns
Strategy: validation
Validate before calling
// Go: check appearance files before invoking the CLI binary
langsDir := filepath.Join(installDir, "appearance", "langs")
if fi, err := os.Stat(langsDir); err != nil || !fi.IsDir() {
return fmt.Errorf("kernel install incomplete: %s missing", langsDir)
} Try / catch
if err := runKernelCLI(args); err != nil && strings.Contains(err.Error(), "appearance files not found") {
// repair installation or reinstall before retrying
} Prevention
- Always deploy the kernel with its full resources/ layout (kernel binary + appearance/), never copy the bare executable.
- Smoke-test `SiYuan-Kernel --help` (or any cheap subcommand) after moving or packaging the binary.
- Pin installs to a packaging script that copies appearance/langs alongside the kernel binary.
When it happens
Trigger: Running any rootCmd subcommand whose PersistentPreRunE executes (i.e. not under the workspace subcommand) when os.Stat(filepath.Join(util.WorkingDir, "appearance", "langs")) reports the directory does not exist — e.g. the kernel binary was copied out of its install tree, or a custom build of SiYuan-Kernel was placed in a bare directory.
Common situations: Downloading SiYuan-Kernel alone without the resources/appearance folder; moving the binary to /usr/local/bin or another isolated path; running a self-compiled kernel from kernel/ without the app/ layout; symlinked or containerized deployments that copy only the executable; macOS installs where the bundle Resources layout changed.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- --attr is required (format: name=value)
- --av and --ids are required
- --av and --key are required
- --av is required
- --av, --key, --item and --value are required
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/0a738c489fb3a09d.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/cli/cmd/root.go:75
sql.FlushQueue()
return nil
},
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// workspace 子命令不需要工作空间校验
if cmd.Parent() != nil && cmd.Parent().Name() == "workspace" {
return nil
}
// 默认工作目录取内核可执行文件所在目录的上一级(打包后的 resources/,appearance/、stage/ 所在目录),
// 而非内核可执行文件所在目录本身(resources/kernel/)。resolveWorkingDir() 会校验 appearance/langs 实际存在,
// 兼容开发态等多种目录布局。
if workingDir := resolveWorkingDir(); workingDir != "" {
util.WorkingDir = workingDir
}
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"View on GitHub (pinned to 9f775e8a12)