siyuan-note/siyuan · error

write data [ ] failed

Error message

write data [%s] failed: %s

What it means

writeTreeByWriteFile persists a parsed document tree as a .sy file via filelock.WriteFile. When the underlying write fails (disk full, permission error, locked file, I/O error), it wraps the path and cause into this message, logs it, and returns a fresh error to the caller of WriteTree.

Solutions

  1. Check free disk space and the read cause (%s in the message) for the underlying OS error.
  2. Verify the workspace data directory is writable by the kernel process.
  3. Close applications holding locks on the .sy file (backup/AV tools) and retry the operation.

Example fix

// before: workspace on read-only mount, WriteTree fails
// after: remount volume read-write or move workspace to writable path, then retry WriteTree
Defensive patterns

Strategy: retry

Validate before calling

// Go
if st, err := os.Stat(filepath.Dir(filePath)); err != nil || !isWritableDir(st) { /* surface config problem first */ }

Try / catch

if err := filesys.WriteTree(tree); err != nil {
    if strings.Contains(err.Error(), "write data") {
        logging.LogErrorf("persist failed: %v", err)
        // check disk space / permissions, then retry once
    }
}

Prevention

When it happens

Trigger: Calling filesys.WriteTree (or any transaction that saves a tree) when the filelock write to the .sy path fails — read-only filesystem, disk quota exceeded, antivirus/backup locking the file, or invalid path.

Common situations: Disk full on the workspace volume, data directory on a read-only or unmounted mount, Windows file lock held by a sync/backup client, or insufficient permissions after moving the workspace.

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@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/034aab3e306ae38d. Report an issue: GitHub.

Appendix: source

Thrown at kernel/filesys/tree.go:514

		}
	}

	if util.ExceedLargeFileWarningSize(len(data)) {
		msg := fmt.Sprintf(util.Langs[util.Lang][268], tree.Root.IALAttr("title")+" "+filepath.Base(filePath), util.LargeFileWarningSize)
		util.PushErrMsg(msg, 7000)
	}

	cache.SetTreeDataInBox(tree.ID, tree.Box, data)
	afterWriteTree(tree)
	size = uint64(len(data))
	return
}

func writeTreeByWriteFile(filePath string, data []byte) (err error) {
	if err = filelock.WriteFile(filePath, data); err != nil {
		msg := fmt.Sprintf("write data [%s] failed: %s", filePath, err)
		logging.LogErrorf("%s", msg)
		err = errors.New(msg)
		return
	}
	return
}

func prepareWriteTree(tree *parse.Tree) (data []byte, filePath string, err error) {
	if err = treenode.SyncTableCellRichInlineChanges(tree.Root); nil != err {
		return
	}
	if err = treenode.CheckSpec(tree); nil != err {
		return
	}
	luteEngine := util.NewLute() // 不关注用户的自定义解析渲染选项

	if nil == tree.Root.FirstChild {
		newP := treenode.NewParagraph("")
		tree.Root.AppendChild(newP)
		tree.Root.SetIALAttr("updated", util.TimeFromID(newP.ID))

View on GitHub (pinned to 9f775e8a12)