siyuan-note/siyuan · critical

dir [ ] has more than 1 file

Error message

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

What it means

During the filesystem status check the kernel writes a probe file (.siyuan/filesys_status_check), lets any third-party sync client act on it, then inspects the resulting directory layout. If the probe directory unexpectedly contains more than one file, an external process (typically a sync client) has modified it, so the kernel reports a fatal filesystem error with the directory listing.

Solutions

  1. Identify the process creating the extra files from the listing in the error message
  2. Exclude the workspace from any third-party sync/antivirus real-time scanning
  3. Pause or uninstall the third-party sync client, then restart the kernel to re-run the check
  4. Move the workspace to a locally-controlled directory
Defensive patterns

Strategy: fallback

Try / catch

onFileSysFatalError((err) => {
    // back up workspace and relocate it to a non-synced directory
});

Prevention

When it happens

Trigger: A third-party sync client materializes extra files (conflict copies, metadata files) inside the probe temp directory while checkFileSysStatus runs; the dir listing passed to the error shows the offending files.

Common situations: OneDrive/Dropbox sync conflicts creating 'file-DESKTOP-XYZ (1).conflict' copies; antivirus quarantine leaving marker files; iCloud 'dataless' file materialization; NAS sync agents writing .tmp sidecar files.

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@8641553a1f (2026-09-11). Data as JSON: /api/errors/c18844b941661305. 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 8641553a1f)