flipped-aurora/gin-vue-admin · error
function client.Object.DeleteMulti() failed, err:
Error message
function client.Object.DeleteMulti() failed, err:
What it means
Wraps a fatal error from the COS SDK's client.Object.DeleteMulti() in TencentCOS.DeleteFiles(). DeleteMulti submits a bulk delete request; a transport-level failure (before the server processes the batch) produces this error. Per-key failures are returned in res.Errors, not here.
Source
Thrown at server/utils/upload/tencent_cos.go:81
return true, nil
}
// DeleteFiles 批量删除:Object.DeleteMulti 一次提交,返回 Errors 逐个失败项。
// PathPrefix 拼接方式与 DeleteFile 一致。
func (*TencentCOS) DeleteFiles(ctx context.Context, keys []string) (failed []DeleteFailure, err error) {
client := NewClient()
objects := make([]cos.Object, 0, len(keys))
for _, k := range keys {
objects = append(objects, cos.Object{Key: global.GVA_CONFIG.TencentCOS.PathPrefix + "/" + k})
}
res, _, err := client.Object.DeleteMulti(ctx, &cos.ObjectDeleteMultiOptions{
Objects: objects,
Quiet: true,
})
if err != nil {
logger.WithCtx(ctx).Mod("upload").Err(err).Error("function client.Object.DeleteMulti() failed")
return nil, errors.New("function client.Object.DeleteMulti() failed, err:" + err.Error())
}
if res != nil {
for _, e := range res.Errors {
failed = append(failed, DeleteFailure{
Key: e.Key,
Err: fmt.Errorf("cos delete %s failed: code=%s, message=%s", e.Key, e.Code, e.Message),
})
}
}
return failed, nil
}
// ListFiles 按前缀列举对象,marker 分页:Marker=cursor,NextMarker→nextCursor,IsTruncated→hasMore。
func (*TencentCOS) ListFiles(ctx context.Context, prefix, cursor string, limit int) (files []FileInfo, nextCursor string, hasMore bool, err error) {
if limit <= 0 {
limit = 100
}View on GitHub (pinned to 3136500ef3)
Solutions
- Check the wrapped err suffix for the COS error code
- Split key lists into chunks of at most 1000 per DeleteMulti call
- Verify credentials and cos:DeleteObject CAM permission
- Retry transient network errors; inspect res.Errors for partial per-key failures
Example fix
// before
cos.DeleteFiles(ctx, allKeys) // >1000 keys may fail the whole request
// after
for i := 0; i < len(keys); i += 1000 {
end := min(i+1000, len(keys))
if _, err := cos.DeleteFiles(ctx, keys[i:end]); err != nil {
return err
}
} Defensive patterns
Strategy: retry
Validate before calling
if len(keys) > 1000 {
return fmt.Errorf("COS DeleteMulti supports at most 1000 objects, got %d", len(keys))
} Try / catch
failed, err := cos.DeleteFiles(ctx, keys)
if err != nil {
if isTransientCOS(err) {
// retry chunk with backoff
}
return nil, err
}
// inspect `failed` for per-key errors (Quiet=true still returns errors) Prevention
- Chunk deletes to <=1000 keys per call
- Verify cos:DeleteObject CAM permission
- Process per-key DeleteFailure results even on success
When it happens
Trigger: Calling DeleteFiles(ctx, keys) when the DeleteMulti request itself fails: auth error, network failure, or request exceeding the batch limit (COS allows up to 1000 objects per call).
Common situations: More than 1000 keys in one call, invalid credentials, CAM lacking cos:DeleteObject for the batch, endpoint unreachable.
Related errors
- function bucketManager.Batch() failed, err:
- function client.Object.Put() failed, err:
- function bucketManager.Delete() failed, err:
- function client.Object.Head() failed, err:
- function client.Bucket.Get() failed, err:
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/63437b4a22c9de63.
Report an issue: GitHub.