siyuan-note/siyuan · error

no such file or directory: %s

Error message

no such file or directory: %s

What it means

Thrown by RollbackRepoSnapshotFile after it writes the decrypted snapshot payload to a temp file (path `from`) and loadTree() returns a nil tree. loadTree reads the file, decrypts it for encrypted notebooks, then runs dataparser.ParseJSONWithoutFix; here its error is discarded (`tree, _ := loadTree(...)`) so any read/decrypt/parse failure collapses into this single message. The literal string is misleading: the temp file usually exists, but its contents could not be parsed into a SiYuan block tree.

Source

Thrown at kernel/model/repository.go:343

		}
		boxID = box.ID

		var destPath, parentHPath string
		rootID := util.GetTreeID(file.Path)
		workingDoc := treenode.GetBlockTree(rootID)
		if needResetTree {
			workingDoc = nil
		}
		destPath, parentHPath, err = getRollbackDockPath(boxID, file.Path, workingDoc)
		if err != nil {
			return
		}

		tree, _ := loadTree(from, util.NewLute())
		if nil == tree {
			msg := fmt.Sprintf("no such file or directory: %s", from)
			logging.LogError(msg)
			err = errors.New(msg)
			return
		}

		tree.Box = boxID
		tree.Path = filepath.ToSlash(strings.TrimPrefix(destPath, util.DataDir+string(os.PathSeparator)+boxID))
		tree.HPath = parentHPath + "/" + tree.Root.IALAttr("title")
		if needResetTree {
			resetTree(tree, "", true)
		}

		if nil != workingDoc && "d" == workingDoc.Type {
			workingDocPath := filepath.Join(util.DataDir, boxID, workingDoc.Path)
			if err = filelock.Remove(workingDocPath); err != nil {
				return
			}
			logging.LogInfof("removed working doc file [%s]", workingDocPath)
		}
		if nil != workingDoc {

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Inspect the kernel log: loadTree logs 'get data [path=%s] failed' or 'decrypt tree ... failed' just before this message — that line names the real cause (read error vs decrypt error vs parse error).
  2. Verify the snapshot object is intact in the repo store and re-download it from cloud if it was partially transferred.
  3. If the snapshot belongs to an encrypted notebook, confirm the notebook is unlocked and retry the rollback; an evicted/missing DEK makes decryption yield unparseable bytes.
  4. Retry after ensuring no other history/repo cleanup or temp-dir prune is running concurrently.
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the file object before rollback: ensure it exists in the index
if file == nil || file.Path == "" || !strings.HasSuffix(file.Path, ".sy") {
    return fmt.Errorf("invalid snapshot file for rollback")
}

Try / catch

err := model.RollbackRepoSnapshotFile(fileID)
if err != nil {
    if strings.Contains(err.Error(), "no such file or directory") {
        // snapshot payload unparseable/corrupt — surface to user, suggest re-download
        util.PushErrMsg("Snapshot file is corrupt or unavailable, try re-downloading", 5000)
    }
    return err
}

Prevention

When it happens

Trigger: Calling the rollback-snapshot-file API on a .sy whose decrypted content is corrupt/truncated, or whose decryption produced garbage (wrong/missing DEK cache evicted mid-operation), or when the temp dir (util.TempDir/repo/rollback) was concurrently cleaned. Also reachable if the just-written temp file was removed before loadTree re-reads it.

Common situations: Rolling back an old encrypted-notebook snapshot after the notebook state changed; partial snapshot data from an interrupted sync; concurrent history/repo cleanup tasks racing with rollback; a manually edited or half-downloaded snapshot object in the dejavu repo store.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/28ac2f6f12625392. Report an issue: GitHub.