{"record":{"id":"40ce8de03305b954","repo":"siyuan-note/siyuan","slug":"dir-s-has-more-than-1-file-n-s","errorCode":null,"errorMessage":"dir [%s] has more than 1 file:\\n%s","messagePattern":"dir \\[(.+?)\\] has more than 1 file:\\\\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"kernel/util/runtime.go","lineNumber":425,"sourceCode":"\t\t\t}\n\n\t\t\tcheckFilenames := bytes.Buffer{}\n\t\t\tfor _, entry := range entries {\n\t\t\t\tif !entry.IsDir() && strings.Contains(entry.Name(), \"check_\") {\n\t\t\t\t\tcheckFilenames.WriteString(entry.Name())\n\t\t\t\t\tcheckFilenames.WriteString(\"\\n\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tlines := strings.Split(strings.TrimSpace(checkFilenames.String()), \"\\n\")\n\t\t\tif 1 < len(lines) {\n\t\t\t\tbuf := bytes.Buffer{}\n\t\t\t\tfor _, line := range lines {\n\t\t\t\t\tbuf.WriteString(\"  \")\n\t\t\t\t\tbuf.WriteString(line)\n\t\t\t\t\tbuf.WriteString(\"\\n\")\n\t\t\t\t}\n\t\t\t\toutput := buf.String()\n\t\t\t\tReportFileSysFatalError(fmt.Errorf(\"dir [%s] has more than 1 file:\\n%s\", dir, output))\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif err = os.RemoveAll(tmp); err != nil {\n\t\t\tReportFileSysFatalError(err)\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc IsCloudDrivePath(workspaceAbsPath string) bool {\n\tif isICloudPath(workspaceAbsPath) {\n\t\treturn true\n\t}\n\n\tif isKnownCloudDrivePath(workspaceAbsPath) {\n\t\treturn true","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/runtime.go#L407-L443","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the listed directory and remove unexpected/foreign files (leave .siyuan internals intact)","Stop third-party sync clients from touching the SiYuan data directory","Move the workspace to a local, non-network filesystem","Restart the kernel so the filesystem status check reruns cleanly"],"exampleFix":"// before\n$ ls \"<data>/tmp-check-dir\"\nfoo  bar   // extra file -> fatal\n// after\n$ rm \"<data>/tmp-check-dir/bar\"   // remove foreign/leftover file\n# restart SiYuan; check passes","handlingStrategy":"validation","validationCode":"// before starting the kernel, ensure data dir is clean and local\nentries, err := os.ReadDir(dataDir)\nif err != nil || len(entries) > 0 && hasForeignFiles(entries) {\n  return errors.New(\"clean unexpected files from the data directory first\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the SiYuan data directory free of third-party sync clients and foreign files","Use local filesystems (ext4/APFS/NTFS), not network mounts or FAT/exFAT, for the workspace","Let a failed filesystem check complete cleanup before restarting the kernel","Investigate any listed extra files rather than blindly re-running the check"],"tags":["filesystem","workspace","sync","self-check"],"backgroundTag":"invalid-state-transition","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}