siyuan-note/siyuan · error
write box conf [%s] failed: %w
Error message
write box conf [%s] failed: %w
What it means
In saveConf0, after the directory is created, filelock.WriteFile(confPath, data) writes conf.json; on failure it calls util.ReportFileSysFatalError(err) (which escalates fatal FS conditions kernel-wide) and returns fmt.Errorf('write box conf [%s] failed: %w', confPath, err). This is the actual disk write of the notebook configuration.
Source
Thrown at kernel/model/box.go:329
func syncBoxConfCryptoBackup(boxID string, boxConf *conf.BoxConf) error {
if !boxConf.Encrypted || boxConf.BoxCrypt == nil {
return nil
}
if needWriteNotebookCryptBackup(boxID, boxConf.BoxCrypt) {
return writeNotebookCryptBackup(boxID, boxConf.BoxCrypt)
}
return nil
}
func (box *Box) saveConf0(data []byte) error {
confPath := filepath.Join(util.DataDir, box.ID, ".siyuan/conf.json")
if err := os.MkdirAll(filepath.Join(util.DataDir, box.ID, ".siyuan"), 0755); err != nil {
return fmt.Errorf("mkdir box conf dir failed: %w", err)
}
if err := filelock.WriteFile(confPath, data); err != nil {
util.ReportFileSysFatalError(err)
return fmt.Errorf("write box conf [%s] failed: %w", confPath, err)
}
invalidateEncryptedPublishAccessCache()
return nil
}
// validateBoxPath 校验 box 内相对路径,拒绝 .. 和绝对路径,确保最终路径在 <DataDir>/<boxID>/ 内。
func (box *Box) validateBoxPath(p string) (string, error) {
return filesys.ValidateBoxRelativePath(box.ID, p)
}
func (box *Box) Ls(p string) (ret []*FileInfo, totals int, err error) {
if _, err = box.validateBoxPath(p); err != nil {
return
}
boxLocalPath := filepath.Join(util.DataDir, box.ID)
if before, ok := strings.CutSuffix(p, ".sy"); ok {
dir := before
absDir := filepath.Join(boxLocalPath, dir)View on GitHub (pinned to 251596fc0d)
Solutions
- Free space on / remount the data volume and retry the save.
- Close other SiYuan instances sharing the workspace (filelock serializes within one instance, not across sync tools).
- On Windows, exclude the workspace from AV/on-demand backup that may lock the file.
- If ReportFileSysFatalError fired, follow the kernel's fatal-FS handling — the workspace is likely unavailable and the kernel may need a restart.
Defensive patterns
Strategy: try-catch
Validate before calling
// Check free space / writability before a configuration save.
if err := filelock.WriteFile(filepath.Join(util.DataDir, ".writeprobe"), []byte{0}); err != nil {
return fmt.Errorf("data dir not writable: %w", err)
} Try / catch
// Fatal FS errors are escalated by ReportFileSysFatalError; surface them prominently.
if err := box.SaveConf(conf); err != nil && strings.Contains(err.Error(), "write box conf") {
showFatalDiskError(errors.Unwrap(err))
} Prevention
- Keep the data volume mounted and below quota.
- Avoid running two SiYuan instances against one workspace.
- On Windows, exclude the workspace from AV/backup tools that lock conf.json.
When it happens
Trigger: Any Box.SaveConf where the write to <DataDir>/<boxID>/.siyuan/conf.json fails: disk full mid-write, the volume unmounted under the kernel, a file-lock/permission failure, or the directory removed by another process between mkdir and write.
Common situations: USB/network drive holding the workspace dropped out; ENOSPC during a large session; antivirus/backup software locking conf.json on Windows; another SiYuan instance (or a sync tool) holds/removes the file.
Related errors
- mkdir box conf dir failed: %w
- prepare box conf [%s] failed: %w
- create dir for publishAccess.json [%s] failed: %s
- write file failed: %s
- resolve assets directory [%s] failed: %w
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/5e01fd2c2b1f3d64.
Report an issue: GitHub.