{"record":{"id":"69f3baaa20f27256","repo":"flipped-aurora/gin-vue-admin","slug":"w-69f3ba","errorCode":null,"errorMessage":"创建临时文件失败: %w","messagePattern":"创建临时文件失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_task.go","lineNumber":269,"sourceCode":"\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}\n\nfunc replaceAutoCodeFileAtomically(target string, content []byte, mode fs.FileMode) error {\n\tif mode == 0 {\n\t\tmode = 0o666\n\t}\n\tdir := filepath.Dir(target)\n\tif err := os.MkdirAll(dir, 0o755); err != nil {\n\t\treturn fmt.Errorf(\"创建目标目录 %s 失败: %w\", dir, err)\n\t}\n\ttmp, err := os.CreateTemp(dir, \".autocode-*\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"创建临时文件失败: %w\", err)\n\t}\n\ttmpName := tmp.Name()\n\tdefer os.Remove(tmpName)\n\tif _, err = tmp.Write(content); err == nil {\n\t\terr = tmp.Sync()\n\t}\n\tif closeErr := tmp.Close(); err == nil {\n\t\terr = closeErr\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"写入临时文件失败: %w\", err)\n\t}\n\tif err = os.Chmod(tmpName, mode.Perm()); err != nil {\n\t\treturn fmt.Errorf(\"设置临时文件权限失败: %w\", err)\n\t}\n\tif err = os.Rename(tmpName, target); err != nil {\n\t\treturn fmt.Errorf(\"原子替换 %s 失败: %w\", target, err)\n\t}","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_task.go#L251-L287","documentation":"After ensuring the target directory exists, replaceAutoCodeFileAtomically creates a unique temp file (pattern .autocode-*) in that directory. If os.CreateTemp fails — usually due to directory write permission, no free inodes/space, or the directory disappearing — this error wraps the failure. The deferred os.Remove keeps failed temp files from lingering.","triggerScenarios":"os.CreateTemp(dir, \".autocode-*\") returns an error: EACCES on the directory, ENOSPC, EMFILE/ENFILE (fd or inode exhaustion), or read-only mount. Raised from prepareAutoCodeFileTask staging writes and rollback restores.","commonSituations":"Service running as a user without write access to the project directory, ulimit -n too low under heavy parallel generation, full disk, or the directory was deleted between MkdirAll and CreateTemp by an external cleaner.","solutions":["Check the wrapped syscall errno and grant write access to the directory for the server process","Verify disk space and inode availability (df -h / df -i)","Raise the process fd limit (ulimit -n) if EMFILE occurs during large generation batches","Ensure nothing (cleanup jobs, antivirus quarantine) removes the directory concurrently"],"exampleFix":"// before\n$ sudo -u www-data test -w server/api/v1 && echo ok || echo no\nno\n// after\nsudo chown -R www-data:www-data server web","handlingStrategy":"retry","validationCode":"dir := filepath.Dir(targetPath)\nif err := unix.Access(dir, unix.W_OK); err != nil {\n    return fmt.Errorf(\"no temp-file create permission in %s\", dir)\n}\nif err := checkDiskSpace(dir, 10*1024*1024); err != nil {\n    return err\n}","typeGuard":null,"tryCatchPattern":"err := commitAutoCodeFileTask(task, publish, persist)\nif err != nil && strings.Contains(err.Error(), \"创建临时文件失败\") {\n    var p *os.PathError\n    if errors.As(err, &p) && errors.Is(p.Err, syscall.EMFILE) {\n        // raise ulimit -n and retry\n    }\n}","preventionTips":["Keep project directories writable by the service account","Raise RLIMIT_NOFILE for processes doing bulk generation","Keep workspaces off read-only or quota-limited mounts","Don't run external cleanup jobs over staging directories during generation"],"tags":["go","filesystem","temp-file","atomic-write"],"backgroundTag":"temp-file-creation-failed","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}