{"record":{"id":"e0322108440c0a4e","repo":"flipped-aurora/gin-vue-admin","slug":"function-client-bucket-get-failed-err","errorCode":null,"errorMessage":"function client.Bucket.Get() failed, err:","messagePattern":"function client\\.Bucket\\.Get\\(\\) failed, err:","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/upload/tencent_cos.go","lineNumber":109,"sourceCode":"\t}\n\treturn failed, nil\n}\n\n// ListFiles 按前缀列举对象，marker 分页：Marker=cursor，NextMarker→nextCursor，IsTruncated→hasMore。\nfunc (*TencentCOS) ListFiles(ctx context.Context, prefix, cursor string, limit int) (files []FileInfo, nextCursor string, hasMore bool, err error) {\n\tif limit <= 0 {\n\t\tlimit = 100\n\t}\n\n\tclient := NewClient()\n\tres, _, err := client.Bucket.Get(ctx, &cos.BucketGetOptions{\n\t\tPrefix:  prefix,\n\t\tMarker:  cursor,\n\t\tMaxKeys: limit,\n\t})\n\tif err != nil {\n\t\tlogger.WithCtx(ctx).Mod(\"upload\").Err(err).Error(\"function client.Bucket.Get() failed\")\n\t\treturn nil, \"\", false, errors.New(\"function client.Bucket.Get() failed, err:\" + err.Error())\n\t}\n\n\tif res != nil {\n\t\tfor _, c := range res.Contents {\n\t\t\tfiles = append(files, FileInfo{\n\t\t\t\tKey:          c.Key,\n\t\t\t\tSize:         c.Size,\n\t\t\t\tLastModified: parseCOSLastModified(c.LastModified),\n\t\t\t})\n\t\t}\n\t\thasMore = res.IsTruncated\n\t\tif hasMore && res.NextMarker != \"\" {\n\t\t\tnextCursor = res.NextMarker\n\t\t} else if hasMore && len(files) > 0 {\n\t\t\t// COS 未返回 NextMarker 时回退用最后一条 key 作为下次 marker\n\t\t\tnextCursor = files[len(files)-1].Key\n\t\t}\n\t}","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/utils/upload/tencent_cos.go#L91-L127","documentation":"Wraps an error from the COS SDK's client.Bucket.Get() in TencentCOS.ListFiles(). Bucket.Get lists bucket contents with prefix/marker pagination; any request-level failure surfaces here.","triggerScenarios":"Calling ListFiles(ctx, prefix, cursor, limit) when Bucket.Get fails: invalid marker, auth failure, wrong region/bucket, or network error.","commonSituations":"Expired credentials, CAM policy missing cos:GetBucket (ListObjects), stale continuation marker, bucket region endpoint unreachable.","solutions":["Check the wrapped err suffix for the COS error code","Grant cos:GetBucket permission to the API key in CAM","Verify Bucket/Region configuration matches the target bucket","Restart listing with an empty cursor if the marker was rejected; retry transient errors"],"exampleFix":"// before\nfiles, marker, hasMore, err := cos.ListFiles(ctx, \"\", staleCursor, 10)\n// after\nif err != nil && strings.Contains(err.Error(), \"InvalidArgument\") {\n    files, marker, hasMore, err = cos.ListFiles(ctx, \"\", \"\", 10)\n}","handlingStrategy":"try-catch","validationCode":"if limit <= 0 || limit > 1000 {\n    limit = 100 // COS Bucket.Get MaxKeys bounds\n}","typeGuard":null,"tryCatchPattern":"files, marker, hasMore, err := cos.ListFiles(ctx, prefix, cursor, limit)\nif err != nil {\n    if strings.Contains(err.Error(), \"AccessDenied\") {\n        // grant cos:GetBucket\n    }\n    return nil, \"\", false, fmt.Errorf(\"list bucket failed: %w\", err)\n}","preventionTips":["Grant cos:GetBucket (ListObjects) permission","Use fresh markers returned by each page","Validate bucket/region config before listing"],"tags":["tencent-cos","list-objects","object-storage"],"backgroundTag":"object-storage-list-failed","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}