siyuan-note/siyuan · critical

dir [ ] has more than 1 file:\n

Error message

dir [%s] has more than 1 file:\n%s

What it means

checkFileSysStatus performs a write/delete self-test inside the data directory and reports a fatal error when a temporary verification directory unexpectedly contains more than one file, indicating filesystem abnormality (e.g. broken sync or inotify weirdness) that would corrupt workspace data.

Solutions

  1. Inspect the listed directory and remove unexpected/foreign files (leave .siyuan internals intact)
  2. Stop third-party sync clients from touching the SiYuan data directory
  3. Move the workspace to a local, non-network filesystem
  4. Restart the kernel so the filesystem status check reruns cleanly

Example fix

// before
$ ls "<data>/tmp-check-dir"
foo  bar   // extra file -> fatal
// after
$ rm "<data>/tmp-check-dir/bar"   // remove foreign/leftover file
# restart SiYuan; check passes
Defensive patterns

Strategy: validation

Validate before calling

// before starting the kernel, ensure data dir is clean and local
entries, err := os.ReadDir(dataDir)
if err != nil || len(entries) > 0 && hasForeignFiles(entries) {
  return errors.New("clean unexpected files from the data directory first")
}

Prevention

When it happens

Trigger: During CheckFileSysStatus, the temporary probe directory created under DataDir lists more than one entry when enumerated, triggering ReportFileSysFatalError with the directory path and its file listing.

Common situations: Third-party sync tools writing extra files into the data directory; filesystems that misbehave on create/list (some network mounts); leftover files from a previously interrupted check; FAT/exFAT quirks on external drives.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at kernel/util/runtime.go:425

			}

			checkFilenames := bytes.Buffer{}
			for _, entry := range entries {
				if !entry.IsDir() && strings.Contains(entry.Name(), "check_") {
					checkFilenames.WriteString(entry.Name())
					checkFilenames.WriteString("\n")
				}
			}
			lines := strings.Split(strings.TrimSpace(checkFilenames.String()), "\n")
			if 1 < len(lines) {
				buf := bytes.Buffer{}
				for _, line := range lines {
					buf.WriteString("  ")
					buf.WriteString(line)
					buf.WriteString("\n")
				}
				output := buf.String()
				ReportFileSysFatalError(fmt.Errorf("dir [%s] has more than 1 file:\n%s", dir, output))
				return
			}
		}

		if err = os.RemoveAll(tmp); err != nil {
			ReportFileSysFatalError(err)
			return
		}
	}
}

func IsCloudDrivePath(workspaceAbsPath string) bool {
	if isICloudPath(workspaceAbsPath) {
		return true
	}

	if isKnownCloudDrivePath(workspaceAbsPath) {
		return true

View on GitHub (pinned to 9f775e8a12)