{"record":{"id":"a1d719b29f058d22","repo":"flipped-aurora/gin-vue-admin","slug":"s-w-a1d719","errorCode":null,"errorMessage":"恢复自动代码文件 %s 失败: %w","messagePattern":"恢复自动代码文件 (.+?) 失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_task.go","lineNumber":239,"sourceCode":"\t\tfile := &task.files[index]\n\t\tcurrentHash, exists, err := hashAutoCodeTarget(file.TargetPath)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif file.Existed && exists && currentHash == file.BeforeHash {\n\t\t\tcontinue\n\t\t}\n\t\tif !exists || currentHash != file.AfterHash {\n\t\t\treturn fmt.Errorf(\"%w: %s\", errAutoCodeFileConflict, file.TargetPath)\n\t\t}\n\t\tif !file.Existed {\n\t\t\tif err = os.Remove(file.TargetPath); err != nil && !errors.Is(err, fs.ErrNotExist) {\n\t\t\t\treturn fmt.Errorf(\"删除新建文件 %s 失败: %w\", file.TargetPath, err)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif err = replaceAutoCodeFileAtomically(file.TargetPath, file.BeforeContent, file.Mode); err != nil {\n\t\t\treturn fmt.Errorf(\"恢复自动代码文件 %s 失败: %w\", file.TargetPath, err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (task *autoCodeFileTask) cleanup() {\n\tif task != nil && task.stagingDir != \"\" {\n\t\t_ = os.RemoveAll(task.stagingDir)\n\t\ttask.stagingDir = \"\"\n\t}\n}\n\nfunc joinAutoCodeRollbackError(cause, rollbackErr error) error {\n\tif rollbackErr == nil {\n\t\treturn cause\n\t}\n\treturn errors.Join(cause, fmt.Errorf(\"回滚自动代码文件失败: %w\", rollbackErr))\n}","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_task.go#L221-L257","documentation":"When rolling back a file that existed before the task, rollback rewrites the saved BeforeContent back via replaceAutoCodeFileAtomically. If that atomic restore fails, the error is wrapped with the target path so the developer knows which file could not be reverted. The underlying cause (temp file, chmod, rename failure) is the wrapped %w error.","triggerScenarios":"replaceAutoCodeFileAtomically(file.TargetPath, file.BeforeContent, file.Mode) fails during rollback: target directory not writable, temp file creation/write failing, or os.Rename unable to replace the target (locked on Windows, cross-device, permission loss).","commonSituations":"Read-only or full disk, directory owned by another user, SELinux/AppArmor blocking writes, Windows file locking by an editor or watcher, or the target file's permissions were hardened after apply.","solutions":["Inspect the wrapped cause (%w) to see which step failed (mkdir / temp file / chmod / rename) and fix that specific condition","Ensure the server process has write permission on the target's directory and the file itself","Stop file watchers/editors holding locks on the path (especially on Windows) and retry","Check disk space and mount status (read-only remount, ENOSPC) for the containing volume"],"exampleFix":"// before\n$ ls -ld server/api/v1\ndr-xr-xr-x  root root\n// after\nsudo chmod u+w server/api/v1  # or chown to the service user","handlingStrategy":"retry","validationCode":"dir := filepath.Dir(targetPath)\nif fi, err := os.Stat(dir); err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"restore dir invalid: %s\", dir)\n}\nif err := unix.Access(dir, unix.W_OK); err != nil {\n    return fmt.Errorf(\"not writable: %s\", dir)\n}","typeGuard":null,"tryCatchPattern":"err := commitAutoCodeFileTask(task, publish, persist)\nif err != nil && strings.Contains(err.Error(), \"恢复自动代码文件\") {\n    // disk/watcher issue; after fixing the environment\n    // restore from git and re-run\ngit checkout -- server/ web/\n}","preventionTips":["Ensure adequate free space before large generation runs","Keep project on a local POSIX filesystem (not NFS/exFAT)","Stop file watchers that hold locks during generation","Check SELinux/AppArmor denials (ausearch -m avc) if writes fail mysteriously"],"tags":["go","filesystem","atomic-write","rollback"],"backgroundTag":"atomic-file-restore-failed","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}