siyuan-note/siyuan · error

localized message from Conf.Language(7) formatted with…

Error message

localized message from Conf.Language(7) formatted with box.Name, path, err (remove failed)

What it means

Box.Remove deletes a file or document path inside a notebook via filelock.Remove. On failure it formats a localized message from Conf.Language(7) with box name, path, and OS error, logs the detail, and returns the message. Reached by removeDoc when deleting documents.

Solutions

  1. Close programs (sync clients, editors) holding the file open
  2. Verify write/delete permissions on <DataDir>/<boxID>/ and its contents
  3. Ensure the workspace volume is mounted read-write
  4. Check the kernel log for 'remove [path=...] failed' to obtain the underlying OS error
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: confirm the path exists and is deletable
p := filepath.Join(util.DataDir, box.ID, path)
if !util.IsExist(p) { return errors.New("nothing to remove") }
info, _ := os.Stat(p)
if info != nil && info.IsDir() && !util.IsEmptyDir(p) { /* expect recursive remove */ }

Try / catch

if err := box.Remove(path); err != nil {
    // localized message; underlying OS error in kernel log 'remove [path=...] failed'
    return err
}

Prevention

When it happens

Trigger: Calling Box.Remove(path) (deleting a document/folder in the UI) when the OS remove fails: permission denied, path is a non-empty directory handled by the underlying remove semantics, file locked by another process, or read-only filesystem.

Common situations: Deleting documents while a sync client holds them open on Windows; workspace on a read-only or unmounted volume; process running as a user without delete permission on the data folder.

Related errors


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

Appendix: source

Thrown at kernel/model/box.go:546

		fromDir := filepath.Join(boxLocalPath, oldDir)
		if util.IsEmptyDir(fromDir) {
			filelock.Remove(fromDir)
		}
	}
	IncSync()
	return nil
}

func (box *Box) Remove(path string) error {
	if _, err := box.validateBoxPath(path); err != nil {
		return err
	}
	boxLocalPath := filepath.Join(util.DataDir, box.ID)
	filePath := filepath.Join(boxLocalPath, path)
	if err := filelock.Remove(filePath); err != nil {
		msg := fmt.Sprintf(Conf.Language(7), box.Name, path, err)
		logging.LogErrorf("remove [path=%s] in box [%s] failed: %s", path, box.ID, err)
		return errors.New(msg)
	}
	IncSync()
	return nil
}

func (box *Box) ListFiles(path string) (ret []*FileInfo) {
	// ListFiles 委托给 Ls,后者已有 validateBoxPath
	fis, _, err := box.Ls(path)
	if err != nil {
		return
	}
	box.listFiles(&fis, &ret)
	return
}

func (box *Box) listFiles(files, ret *[]*FileInfo) {
	for _, file := range *files {
		if file.isdir {

View on GitHub (pinned to 9f775e8a12)