flipped-aurora/gin-vue-admin · warning
文件不存在
Error message
文件不存在
What it means
This error is returned by Local.DeleteFile when os.Stat reports that the file corresponding to the given key does not exist under the local store path. The library checks existence before acquiring the delete lock so callers get a clear 'file missing' signal instead of an opaque remove error.
Source
Thrown at server/utils/upload/local.go:91
//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Local
//@function: DeleteFile
//@description: 删除文件
//@param: key string
//@return: error
func (l *Local) DeleteFile(ctx context.Context, key string) error {
p, err := l.localPath(ctx, key)
if err != nil {
return err
}
// 检查文件是否存在
if _, err := os.Stat(p); os.IsNotExist(err) {
return errors.New("文件不存在")
}
// 使用文件锁防止并发删除
mu.Lock()
defer mu.Unlock()
err = os.Remove(p)
if err != nil {
return errors.New("文件删除失败: " + err.Error())
}
return nil
}
// localPath 校验 key 并拼接出本地存储的绝对路径,复用 DeleteFile 中的路径穿越防护逻辑。
func (*Local) localPath(ctx context.Context, key string) (string, error) {
// 检查 key 是否为空
if key == "" {View on GitHub (pinned to 3136500ef3)
Solutions
- Treat this as an idempotent success if your delete flow tolerates missing files (check the error message for 文件不存在 and skip).
- Verify the key exists first with the Exists() method, or list files via ListFiles to confirm the key.
- Confirm local.store-path in config matches the environment where the file was originally uploaded.
- If it happens in batch deletes, filter DeleteFiles input against Exists() results beforehand.
Example fix
// before
err := local.DeleteFile(ctx, key)
// after
exists, err := local.Exists(ctx, key)
if err == nil && exists {
err = local.DeleteFile(ctx, key)
} // missing files are silently skipped (idempotent delete) Defensive patterns
Strategy: validation
Validate before calling
exists, err := local.Exists(ctx, key)
if err != nil {
return err
}
if !exists {
return nil // already gone; idempotent no-op
} Try / catch
err := local.DeleteFile(ctx, key)
if err != nil && err.Error() == "文件不存在" {
return nil // treat as success (idempotent delete)
}
if err != nil {
return err
} Prevention
- Treat file deletion as idempotent — missing means already deleted, not failure.
- Check Exists() before deleting in interactive flows.
- Keep config's store-path consistent across replicas/environments sharing a DB.
- Serialize deletes for the same key (or accept races) in cleanup jobs.
When it happens
Trigger: Calling DeleteFile (directly or via DeleteFiles) with a key that was never uploaded, was already deleted, or was deleted outside the app; also when StorePath configuration changed so the key no longer resolves to the original location.
Common situations: Double-delete race where two requests delete the same key; cleanup jobs running concurrently with user deletes; switching environments (dev/prod) where the DB still references files absent on disk; typo'd key from a stale frontend cache.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/b05ebf4c3ef35c40.
Report an issue: GitHub.