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

  1. Check the wrapped err suffix for the COS error code
  2. Split key lists into chunks of at most 1000 per DeleteMulti call
  3. Verify credentials and cos:DeleteObject CAM permission
  4. 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

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


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/63437b4a22c9de63. Report an issue: GitHub.