{"record":{"id":"5f72fb3cfc1119dc","repo":"siyuan-note/siyuan","slug":"write-publishaccess-json-s-failed-s","errorCode":null,"errorMessage":"write publishAccess.json [%s] failed: %s","messagePattern":"write publishAccess\\.json \\[(.+?)\\] failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/publish_access.go","lineNumber":140,"sourceCode":"\terr = os.MkdirAll(filepath.Dir(publishAccessPath), 0755)\n\tif err != nil {\n\t\tmsg := fmt.Sprintf(\"create dir for publishAccess.json [%s] failed: %s\", publishAccessPath, err)\n\t\tlogging.LogError(msg)\n\t\terr = errors.New(msg)\n\t\treturn\n\t}\n\n\tdata, err := gulu.JSON.MarshalJSON(inputPublishAccess)\n\tif err != nil {\n\t\tlogging.LogErrorf(\"marshal publishAccess.json [%s] failed: %s\", publishAccessPath, err)\n\t\treturn\n\t}\n\n\terr = filelock.WriteFile(publishAccessPath, data)\n\tif err != nil {\n\t\tmsg := fmt.Sprintf(\"write publishAccess.json [%s] failed: %s\", publishAccessPath, err)\n\t\tlogging.LogError(msg)\n\t\terr = errors.New(msg)\n\t\treturn\n\t}\n\treturn\n}\n\nfunc GetInvisiblePublishAccess(inputPublishAccess PublishAccess) (outputPublishAccess PublishAccess) {\n\toutputPublishAccess = filterInvisiblePublishAccess(inputPublishAccess)\n\toutputPublishAccess = appendEncryptedBoxesToPublishAccess(outputPublishAccess)\n\treturn\n}\n\nfunc filterInvisiblePublishAccess(inputPublishAccess PublishAccess) (outputPublishAccess PublishAccess) {\n\toutputPublishAccess = PublishAccess{}\n\tfor _, item := range inputPublishAccess {\n\t\tif !item.Visible {\n\t\t\toutputPublishAccess = append(outputPublishAccess, item)\n\t\t}\n\t}","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/publish_access.go#L122-L158","documentation":"Thrown by SetPublishAccess() when filelock.WriteFile fails to write the serialized publishAccess.json after the directory was successfully created and data marshaled. filelock.WriteFile acquires a file lock then writes the bytes; failure indicates a low-level I/O problem at write time.","triggerScenarios":"Calling SetPublishAccess() where os.MkdirAll and gulu.JSON.MarshalJSON both succeed, but the final file write fails. Causes include: disk full during write, the file is locked by another process exclusively, permission revoked between mkdir and write, or the filesystem was remounted read-only mid-operation.","commonSituations":"Disk filled up between creating the directory and writing the file. Another SiYuan instance or process holds an exclusive lock on publishAccess.json. Antivirus or backup software locked the file transiently on Windows. The filesystem was remounted read-only after startup (e.g., ext4 errors triggering read-only remount).","solutions":["Check disk space: df -h and ensure there is free space on the data volume.","Ensure no other SiYuan instance is running against the same data directory (filelock contention).","Check dmesg/syslog for filesystem errors that may have triggered a read-only remount.","Retry the operation after freeing space or resolving the lock; if transient (AV scan, backup), it may succeed on retry.","Verify write permissions are still intact on the .siyuan directory."],"exampleFix":"# before — disk full or lock contention\n\n# after — free space and retry\n# Check: df -h\n# Clear space or expand volume, then:\n# The frontend 'Save' button will retry SetPublishAccess automatically.\n\n# If lock contention from a stale process:\n# ps aux | grep siyuan\n# kill the stale process, then retry.","handlingStrategy":"retry","validationCode":"// Check available disk space before writing\nvar stat syscall.Statfs_t\nif err := syscall.Statfs(util.DataDir, &stat); err == nil {\n    freeBytes := stat.Bavail * uint64(stat.Bsize)\n    if freeBytes < 1024*1024 { // less than 1MB free\n        return errors.New(\"insufficient disk space to save publish access settings\")\n    }\n}","typeGuard":null,"tryCatchPattern":"err := model.SetPublishAccess(input)\nif err != nil && strings.Contains(err.Error(), \"write publishAccess.json\") {\n    // Could be transient (disk full, lock contention) — retry once\n    time.Sleep(500 * time.Millisecond)\n    err = model.SetPublishAccess(input)\n    if err != nil {\n        log.Printf(\"publishAccess.json write failed after retry: %v\", err)\n    }\n}","preventionTips":["Monitor disk space and alert before it fills.","Ensure no other SiYuan instance writes to the same data directory.","On Windows, exclude the data directory from AV real-time scanning if file locks are frequent."],"tags":["filesystem","publish","io","disk-full","filelock","runtime"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}