flipped-aurora/gin-vue-admin · error
原子发布 %s 失败: %w
Error message
原子发布 %s 失败: %w
What it means
Raised when the final atomic publish step os.Rename(stagedPath, targetPath) fails. Staged content is written to a temp file in the project root and moved into place with rename for atomicity; rename failures abort the publish of that file and trigger rollback of already-published files.
Source
Thrown at server/service/system/auto_code_task.go:209
currentHash, exists, err := hashAutoCodeTarget(file.TargetPath)
if err != nil {
return false, err
}
if exists && currentHash == file.AfterHash {
if removeErr := os.Remove(file.StagedPath); removeErr != nil && !errors.Is(removeErr, fs.ErrNotExist) {
return false, fmt.Errorf("清理重复 staging 文件失败: %w", removeErr)
}
file.StagedPath = ""
return false, nil
}
if exists != file.Existed || (file.Existed && currentHash != file.BeforeHash) {
return false, fmt.Errorf("%w: %s", errAutoCodeFileConflict, file.TargetPath)
}
if err = os.MkdirAll(filepath.Dir(file.TargetPath), 0o755); err != nil {
return false, fmt.Errorf("创建目标目录 %s 失败: %w", filepath.Dir(file.TargetPath), err)
}
if err = os.Rename(file.StagedPath, file.TargetPath); err != nil {
return false, fmt.Errorf("原子发布 %s 失败: %w", file.TargetPath, err)
}
file.StagedPath = ""
return true, nil
}
func (task *autoCodeFileTask) rollback(applied []int) error {
for i := len(applied) - 1; i >= 0; i-- {
index := applied[i]
if index < 0 || index >= len(task.files) {
return fmt.Errorf("自动代码回滚索引无效: %d", index)
}
file := &task.files[index]
currentHash, exists, err := hashAutoCodeTarget(file.TargetPath)
if err != nil {
return err
}
if file.Existed && exists && currentHash == file.BeforeHash {
continueView on GitHub (pinned to 3136500ef3)
Solutions
- Ensure the repo root, server/ and web/ trees live on the same local filesystem (avoid mounting web/ on a different device than the root that hosts the staging dir)
- Fix permissions on the target directory/existing file so the server process can replace it
- Verify the target path is a regular file, not a directory
- Re-run after closing processes that lock target files; check mount layout if EXDEV is reported
Example fix
// before: web on separate mount -> EXDEV on rename /dev/sdb1 on /project/web type ext4 // after: keep web/ inside the repo root filesystem (same device as staging dir) $ mv /mnt/otherdisk/web ./web # then regenerate/re-run
Defensive patterns
Strategy: validation
Validate before calling
func sameDevice(a, b string) error {
aInfo, err := os.Stat(a)
if err != nil {
return err
}
bInfo, err := os.Stat(b)
if err != nil {
return err
}
aSys, bSys := aInfo.Sys().(*syscall.Stat_t), bInfo.Sys().(*syscall.Stat_t)
if aSys.Dev != bSys.Dev {
return fmt.Errorf("%s and %s on different devices (rename would fail with EXDEV)", a, b)
}
return nil
}
// check repo root (staging parent) vs each target's directory before committing Try / catch
if err := commitAutoCodeFileTask(task, publishPreparedAutoCodeFile, persist); err != nil {
if strings.Contains(err.Error(), "原子发布") {
var pathErr *os.LinkError
if errors.As(err, &pathErr) && errors.Is(pathErr, syscall.EXDEV) {
// reconfigure layout so staging dir and targets share one filesystem
}
}
} Prevention
- Keep the auto-code root, server/ and web/ on the same local filesystem
- Avoid symlinking web/ or server/ into other mounts; the staging dir lives in the repo root
- Ensure target files are regular files owned/writable by the service user
- Close editors/build tools that may hold or replace target files during generation
When it happens
Trigger: os.Rename fails with EXDEV (staging dir and target on different filesystems/mounts), permission denied on the target directory or existing target file, target became a directory, or the staged file was removed mid-task.
Common situations: web/ or server/ is a separate mount/symlink into another filesystem while the staging dir lives in the repo root (EXDEV); target file owned by root or another user; editors/watchers holding the target open with delete restrictions on some platforms; Docker volume boundary between staging and target.
Related errors
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/0df4856d182366cc.
Report an issue: GitHub.