Skip to content

api: migrate response types to std::expected<T, Error> (or tl::expected for C++17)#238

Merged
harshavardhana merged 4 commits into
minio:mainfrom
jiuker:fix-issue-225
Jul 7, 2026
Merged

api: migrate response types to std::expected<T, Error> (or tl::expected for C++17)#238
harshavardhana merged 4 commits into
minio:mainfrom
jiuker:fix-issue-225

Conversation

@jiuker

@jiuker jiuker commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

…ted for C++17)

fix issue

## Problem

\`Response\` bundles success state and error in one struct, and callers signal "did it work?" with \`explicit operator bool()\` (see \`include/miniocpp/response.h:32-71\`). It works but:

- Forgetting to check \`if (!resp)\` is silent — you can read \`resp.etag\` on a failed response and get an empty string
- Every operation duplicates the bool-conversion gate
- Error and success paths share memory in every response struct

## Suggested approach

\`\`\`cpp
std::expected<PutObjectResponse, error::Error> PutObject(PutObjectArgs args);
\`\`\`

Now \`auto r = client.PutObject(args)\` either holds the response or the error, never both. \`r.has_value()\` / \`*r\` for the happy path; \`r.error()\` otherwise. Compiler catches "you didn't check" via \`[[nodiscard]]\`.

## Constraints

- \`std::expected\` is C++23 only. For C++17 compatibility, vendor \`tl::expected\` (header-only, well-tested) or write a minimal in-tree implementation. Doesn't require #222 (C++20 opt-in) to land.
- This is a **breaking API change** for every method. Plan a major version bump or a parallel new-API namespace.
- Naturally pairs with #221 (ParseXML view-not-copy) since both touch the response types.

## Impact

**Large.** Single biggest API quality win — shifts error handling from runtime convention to compile-time type-enforcement.

## Roadmap

Tier 3 item from the C++ modernization audit. Highest-leverage of the modernization items but also the biggest API surface change.

Summary by CodeRabbit

  • New Features

    • The client now returns a consistent result type for many operations, making success and error handling more explicit.
    • Async calls now follow the same result pattern as synchronous calls.
  • Bug Fixes

    • Improved error propagation for object, bucket, and multipart operations.
    • XML parsing failures now surface more reliably instead of being hidden in response objects.
    • Updated examples and tests to match the new response handling style.

…ted for C++17)

api: migrate response types to std::expected<T, Error> (or tl::expected for C++17)
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jiuker, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 5 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f51d09cd-378d-40b7-b3e3-5ae597698b44

📥 Commits

Reviewing files that changed from the base of the PR and between c50e502 and 15ef614.

📒 Files selected for processing (34)
  • examples/DeleteBucketEncryption.cc
  • examples/DeleteBucketLifecycle.cc
  • examples/DeleteBucketNotification.cc
  • examples/DeleteBucketReplication.cc
  • examples/DeleteObjectLockConfig.cc
  • examples/DisableObjectLegalHold.cc
  • examples/EnableObjectLegalHold.cc
  • examples/GetBucketEncryption.cc
  • examples/GetBucketLifecycle.cc
  • examples/GetBucketNotification.cc
  • examples/GetBucketPolicy.cc
  • examples/GetBucketReplication.cc
  • examples/GetBucketVersioning.cc
  • examples/GetObjectLockConfig.cc
  • examples/GetObjectRetention.cc
  • examples/GetPresignedObjectUrl.cc
  • examples/GetPresignedPostFormData.cc
  • examples/IsObjectLegalHoldEnabled.cc
  • examples/ListObjects.cc
  • examples/ListenBucketNotification.cc
  • examples/RemoveObjects.cc
  • examples/SelectObjectContent.cc
  • examples/SetBucketEncryption.cc
  • examples/SetBucketNotification.cc
  • examples/SetBucketReplication.cc
  • examples/SetBucketVersioning.cc
  • examples/SetObjectLockConfig.cc
  • examples/StatObject.cc
  • include/miniocpp/baseclient.h
  • src/baseclient.cc
  • src/c_api.cc
  • src/client.cc
  • src/providers.cc
  • tests/tests.cc
📝 Walkthrough

Walkthrough

This PR introduces tl::expected-based Result<T> error handling throughout the library, replacing exception/error-embedded-response patterns. BaseClient, Client, Credentials::ParseXML, and response ParseXML methods now return Result<T>. Providers, select handling, examples, and tests are updated accordingly.

Changes

Result migration

Layer / File(s) Summary
expected library and Result alias
include/tl/expected.hpp, include/miniocpp/result.h, include/miniocpp/error.h
Vendors a full tl::expected<T,E> implementation, adds minio::Result<T> alias, and updates error::make to return tl::expected via tl::make_unexpected.
Response parsing contracts
include/miniocpp/response.h, src/response.cc
ParseXML methods across all response types return Result<...>; error::Error-forwarding constructors removed.
BaseClient request/response flow
include/miniocpp/baseclient.h, src/baseclient.cc
GetErrorResponse, execute, Execute, GetRegion, and all sync/async S3 operations return Result<T>/std::future<Result<T>>.
Client object operations
include/miniocpp/client.h, src/client.cc
ComposeObject, CopyObject, DownloadObject, PutObject, GetObject, UploadObject and multipart helpers/async overloads converted to Result<T>; list/remove iterators adjusted.
Credentials and providers
include/miniocpp/credentials.h, src/credentials.cc, src/providers.cc
Credentials::ParseXML returns Result<Credentials>; provider fetch paths use direct Credentials{error::Error(...)} or parse-result handling.
Select error construction
src/select.cc
SelectResult error paths construct error::Error directly instead of via error::make.
Examples
examples/*.cc
All example programs use auto for response variables, check truthiness with if(resp), dereference via resp->..., and call resp.error().String().
Tests
tests/tests.cc
Sync/async test coverage updated to Result checks, pointer-style payload access, and resp.error().String().

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

  • minio/minio-cpp#229: Both PRs touch the same BaseClient/Client async method signatures in the same headers, changing how std::future results are returned.
  • minio/minio-cpp#234: Both PRs modify XML parsing for ListObjectsResponse in include/miniocpp/response.h/src/response.cc.

Suggested reviewers: harshavardhana

Poem

A rabbit hops through code so neat,
Where errors once could hide, incomplete—
Now Result<T> shows its face,
No silent throw, no hidden trace.
Hop, hop, hooray, the build compiles clean! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main API migration to expected-style result types and matches the change set.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
tmpfile.19088 (1)

1-89: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Stray temp file appears accidentally committed.

tmpfile.19088 looks like a local scratch artifact (e.g., piped output of a file-listing command) rather than an intentional source file. Recommend removing it from the PR.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tmpfile.19088` around lines 1 - 89, Remove the accidentally committed scratch
file from the change set: tmpfile.19088 appears to be a transient file-listing
artifact, not a real source artifact. Delete it from the PR and keep the rest of
the affected project files unchanged; if needed, verify no build or test
references depend on tmpfile.19088.
tests/tests.cc (1)

1319-1326: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Check the async results before reading exist. fe1.get()->exist/fe2/fe3 dereference the Result<BucketExistsResponse> without an error check; if any call fails, this block can crash instead of failing the test cleanly. Store each get() result, check !resp, then read ->exist.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/tests.cc` around lines 1319 - 1326, The concurrent BucketExistsAsync()
test reads fe1.get()->exist, fe2.get()->exist, and fe3.get()->exist without
first verifying the returned Result objects succeeded. Update the test in
tests.cc to capture each get() result from BucketExistsAsync, check each
response for failure before accessing exist, and only then evaluate the bucket
existence values. Keep the cleanup and runtime_error path in the same test block
so failures are reported cleanly instead of crashing.
src/client.cc (1)

1378-1393: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Return the multipart error before dereferencing cmu_resp. CompleteMultipartUpload can fail here; the abort still runs, but PutObjectResponse(std::move(*cmu_resp)) dereferences a disengaged Result and drops the error.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/client.cc` around lines 1378 - 1393, Handle the failure from
CompleteMultipartUpload in client.cc before constructing PutObjectResponse:
cmu_resp can be empty when multipart completion fails, so return or propagate
that error instead of unconditionally dereferencing it. Keep the
AbortMultipartUpload path in the same branch, and update the PutObjectResponse
return site to only use std::move(*cmu_resp) after confirming cmu_resp is
engaged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@include/miniocpp/baseclient.h`:
- Around line 191-192: Update the stale API comments in baseclient.h to match
the current migration: the async overloads in the relevant BaseClient
declarations now return std::future<Result<T>>, and the sync methods also return
Result<T>, so remove the claim that they are “non-breaking” and that sync
methods remain unchanged. Keep the wording aligned with the actual signatures
around the async overload section so maintainers are not misled about
compatibility.
- Line 138: BaseClient::GetBucketPolicy has an invalid error path because
Execute(req) can return a failing Result<Response> with no response value, so
dereferencing resp in the failure branch is unsafe and loses the real error.
Update GetBucketPolicy in BaseClient to propagate the failure by returning
tl::make_unexpected(resp.error()) when Execute(req) fails, while keeping the
successful path unchanged and using the existing
GetBucketPolicyResponse/Execute(req) symbols to locate the fix.
- Line 144: The Windows GetObject wrappers are still using the old return type,
so update the `_WIN32` `GetObjectA` and `GetObjectW` methods in `BaseClient` to
return `Result<GetObjectResponse>` and forward the `GetObject(args)` result
directly. Make sure the wrapper signatures and any matching implementation
details stay aligned with the new `GetObject()` return type so Windows builds
compile cleanly.

In `@src/baseclient.cc`:
- Around line 791-796: The error handling in GetBucketNotification is inverted:
when Execute(req) fails, the code currently dereferences an empty resp and
returns a normal response instead of propagating the failure. Update the
GetBucketNotificationResponse path so the success branch parses resp->data, and
the failure branch returns tl::make_unexpected(resp.error()) using the
Execute(req) result. Keep the fix localized to the GetBucketNotification logic
in src/baseclient.cc and preserve the existing ParseXML response construction on
success.
- Around line 1426-1432: Guard the failure path in the bucket-creation flow
inside the `Execute`/`MakeBucketResponse` sequence in `baseclient.cc`: `resp`
may hold an error, so do not unconditionally dereference it with
`std::move(*resp)`. Update the logic to return the error immediately when
`Execute(req)` fails, and only enter the `region_map_` update and
`MakeBucketResponse` construction when `resp` is valid.
- Around line 843-847: The error branch in Execute handling is dereferencing an
empty Result<Response> by using std::move(*resp) after a failed call. Update the
GetBucketReplicationResponse path to return the underlying failure using
tl::make_unexpected on the Execute result’s error instead, and keep the
successful ParseXML branch in GetBucketReplicationResponse unchanged.
- Around line 1038-1045: In GetObjectRetentionResponse handling after
Execute(req), the error path currently dereferences a valueless resp by moving
*resp, which is undefined behavior. Update the if (!resp) branch to return the
error directly using resp.error() via tl::make_unexpected, while keeping the
existing NoSuchObjectLockConfiguration special case and preserving the
surrounding GetObjectRetentionResponse logic.
- Around line 869-873: The failure path in GetBucketTagsResponse handling is
dereferencing resp after Execute(req) returns a non-success result, which can
cause undefined behavior instead of propagating the request error. Update the
logic around Execute(req) and GetBucketTagsResponse so the error response is
returned directly from resp without dereferencing it, preserving the failure
details and avoiding invalid access.
- Around line 817-821: The GetBucketPolicyResponse handling in the Execute
failure path is dereferencing a disengaged Result, which can cause undefined
behavior and hide the real error. Update the response flow in the bucket policy
method so the failure branch returns the error from Execute directly instead of
using std::move(*resp), and keep the success branch using
GetBucketPolicyResponse(resp->data) as-is.

In `@src/client.cc`:
- Around line 216-219: The `ListObjectsResponse` fallback in `src/client.cc`
contains a dead `if (resp)` branch because all successful `resp` paths already
return earlier in the function. Simplify the logic around the `ListObjects`
handling by removing the unreachable condition and keeping a single return of
the empty `ListObjectsResponse`, using the existing `resp` check and the
surrounding region-lookup flow to locate the block.
- Around line 813-821: Propagate the `CompleteMultipartUpload` failure before
constructing the final response: in `PutObject` after the
`CompleteMultipartUpload(cmu_args)` call, check the `resp` `Result` and return
the error immediately if it is not successful. Only run the progress callback
and build `PutObjectResponse` when `resp` contains a value, using the
`PutObject`/`CompleteMultipartUpload` flow and the `resp` symbol to locate the
fix.

In `@src/providers.cc`:
- Around line 262-265: The AssumeRole parsing path is discarding the real parse
error and then rechecking creds_ in a way that can treat valid-but-empty
credentials as failure. Update the Credentials::ParseXML handling in the
AssumeRole fetch flow to follow the same pattern as LdapIdentityProvider::Fetch
and CertificateIdentityProvider::Fetch: keep the parse result, inspect its
success directly, and propagate parse_res.error() instead of replacing it with a
generic Credentials::error::Error message. Apply the same fix to both affected
call sites in the provider implementation so diagnostics stay consistent.

---

Outside diff comments:
In `@src/client.cc`:
- Around line 1378-1393: Handle the failure from CompleteMultipartUpload in
client.cc before constructing PutObjectResponse: cmu_resp can be empty when
multipart completion fails, so return or propagate that error instead of
unconditionally dereferencing it. Keep the AbortMultipartUpload path in the same
branch, and update the PutObjectResponse return site to only use
std::move(*cmu_resp) after confirming cmu_resp is engaged.

In `@tests/tests.cc`:
- Around line 1319-1326: The concurrent BucketExistsAsync() test reads
fe1.get()->exist, fe2.get()->exist, and fe3.get()->exist without first verifying
the returned Result objects succeeded. Update the test in tests.cc to capture
each get() result from BucketExistsAsync, check each response for failure before
accessing exist, and only then evaluate the bucket existence values. Keep the
cleanup and runtime_error path in the same test block so failures are reported
cleanly instead of crashing.

In `@tmpfile.19088`:
- Around line 1-89: Remove the accidentally committed scratch file from the
change set: tmpfile.19088 appears to be a transient file-listing artifact, not a
real source artifact. Delete it from the PR and keep the rest of the affected
project files unchanged; if needed, verify no build or test references depend on
tmpfile.19088.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fd0bfa6e-d757-4dd5-8f03-87ce572a5499

📥 Commits

Reviewing files that changed from the base of the PR and between 06271b2 and a32a510.

📒 Files selected for processing (15)
  • include/miniocpp/baseclient.h
  • include/miniocpp/client.h
  • include/miniocpp/credentials.h
  • include/miniocpp/error.h
  • include/miniocpp/response.h
  • include/miniocpp/result.h
  • include/tl/expected.hpp
  • src/baseclient.cc
  • src/client.cc
  • src/credentials.cc
  • src/providers.cc
  • src/response.cc
  • src/select.cc
  • tests/tests.cc
  • tmpfile.19088

Comment thread include/miniocpp/baseclient.h
Comment thread include/miniocpp/baseclient.h
Comment thread include/miniocpp/baseclient.h Outdated
Comment thread src/baseclient.cc
Comment thread src/baseclient.cc Outdated
Comment thread src/baseclient.cc
Comment thread src/baseclient.cc
Comment thread src/client.cc Outdated
Comment thread src/client.cc
Comment thread src/providers.cc Outdated
apply suggestion

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (22)
examples/DeleteBucketEncryption.cc (1)

36-44: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Use auto for the delete-bucket-encryption response
client.DeleteBucketEncryption(args) returns Result<DeleteBucketEncryptionResponse>, so this should match the other examples: auto resp = client.DeleteBucketEncryption(args);. The current DeleteBucketEncryptionResponse resp will not compile.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/DeleteBucketEncryption.cc` around lines 36 - 44, The
delete-bucket-encryption example is using the concrete response type instead of
the returned Result type, which will not compile. Update the response
declaration in DeleteBucketEncryptionResponse handling to use auto with
client.DeleteBucketEncryption(args), matching the other examples and keeping the
existing success/error handling unchanged.
examples/SelectObjectContent.cc (1)

56-64: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Use auto for resp
examples/SelectObjectContent.cc:56-57 — client.SelectObjectContent(args) returns Result<SelectObjectContentResponse>, so this concrete SelectObjectContentResponse declaration is a type mismatch and the example won’t compile.

Proposed fix
-  minio::s3::SelectObjectContentResponse resp =
-      client.SelectObjectContent(args);
+  auto resp = client.SelectObjectContent(args);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/SelectObjectContent.cc` around lines 56 - 64, The
SelectObjectContent example declares resp as the concrete
SelectObjectContentResponse even though client.SelectObjectContent(args) returns
a Result<SelectObjectContentResponse>, which causes a compile-time type
mismatch. Update the SelectObjectContentResponse resp declaration in
SelectObjectContent to use auto so the result type is inferred correctly, while
keeping the existing success/error handling logic unchanged.
examples/DeleteBucketLifecycle.cc (1)

36-46: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Use Result<DeleteBucketLifecycleResponse> here
Client::DeleteBucketLifecycle() returns Result<DeleteBucketLifecycleResponse>, so the current DeleteBucketLifecycleResponse declaration doesn’t match and resp.error() won’t compile. Use auto resp = client.DeleteBucketLifecycle(args); or an explicit Result<DeleteBucketLifecycleResponse>.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/DeleteBucketLifecycle.cc` around lines 36 - 46, The
DeleteBucketLifecycle example is using the response type directly instead of the
Result wrapper returned by Client::DeleteBucketLifecycle. Update the resp
declaration in DeleteBucketLifecycle.cc to use auto or an explicit
Result<DeleteBucketLifecycleResponse>, then keep the existing success/error
handling against the Result object so resp.error() compiles correctly.
examples/DeleteBucketNotification.cc (1)

36-46: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Use auto for the delete response
client.DeleteBucketNotification(args) returns Result<DeleteBucketNotificationResponse>, so this declaration won’t compile and resp.error() is only available on the result type.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/DeleteBucketNotification.cc` around lines 36 - 46, The
DeleteBucketNotification example is declaring the return value as the concrete
response type instead of the Result wrapper returned by
client.DeleteBucketNotification(args), which breaks compilation and prevents
access to error(). Update the resp declaration in DeleteBucketNotification to
use auto so it preserves the Result<DeleteBucketNotificationResponse> type, and
keep the existing success/error handling logic unchanged.
examples/DeleteBucketReplication.cc (1)

36-46: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Use auto for resp here too. It matches DeleteBucketPolicy.cc and DeleteBucketTags.cc and avoids repeating the concrete response type.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/DeleteBucketReplication.cc` around lines 36 - 46, The response
variable in the DeleteBucketEncryption example is using an explicit concrete
type, but it should match the other examples and use auto instead. Update the
resp declaration in the DeleteBucketEncryption example to use auto, keeping the
existing call to client.DeleteBucketEncryption(args) and the subsequent response
handling unchanged.
examples/DisableObjectLegalHold.cc (1)

37-46: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use auto for DisableObjectLegalHold result client.DisableObjectLegalHold(args) returns Result<DisableObjectLegalHoldResponse>, so the explicit DisableObjectLegalHoldResponse declaration makes the later .error() access invalid. Switch to auto here, as in the other updated examples.

🔧 Proposed fix
-  minio::s3::DisableObjectLegalHoldResponse resp =
-      client.DisableObjectLegalHold(args);
+  auto resp = client.DisableObjectLegalHold(args);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/DisableObjectLegalHold.cc` around lines 37 - 46, The
DisableObjectLegalHold example is declaring the result as
DisableObjectLegalHoldResponse, but client.DisableObjectLegalHold(args) returns
a Result wrapper, so the later resp.error() access is invalid. Update the
variable in DisableObjectLegalHold.cc to use auto for the DisableObjectLegalHold
call result, matching the pattern used in the other examples, and keep the
existing success/error handling unchanged.
examples/DeleteObjectLockConfig.cc (1)

36-45: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use auto for the DeleteObjectLockConfig result
client.DeleteObjectLockConfig(args) returns Result<DeleteObjectLockConfigResponse>, so the explicit DeleteObjectLockConfigResponse declaration drops the error() accessor and breaks this branch. Match the other updated examples with auto resp = client.DeleteObjectLockConfig(args);

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/DeleteObjectLockConfig.cc` around lines 36 - 45, The
DeleteObjectLockConfig example is using the concrete response type for the
result of client.DeleteObjectLockConfig(args), which strips the Result wrapper
and prevents access to resp.error() in the failure branch. Update the
declaration in DeleteObjectLockConfig example to use auto for the
DeleteObjectLockConfigConfig/response result so it preserves the
Result<DeleteObjectLockConfigResponse> type, matching the other updated examples
and keeping both the success and error handling paths valid.
examples/EnableObjectLegalHold.cc (1)

37-46: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use auto for the result here. EnableObjectLegalHoldResponse is the concrete response type, so if (resp) and resp.error() won’t work on this declaration; keep it as the returned result type instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/EnableObjectLegalHold.cc` around lines 37 - 46, The response
variable in EnableObjectLegalHold should be declared with auto rather than the
concrete EnableObjectLegalHoldResponse type, since the returned result object is
what supports both the boolean check and error() access. Update the declaration
in the EnableObjectLegalHold example to preserve the
client.EnableObjectLegalHold(args) return type, then keep the existing if (resp)
/ resp.error() handling unchanged.
examples/SetBucketReplication.cc (1)

50-58: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use auto for resp hereclient.SetBucketReplication(args) returns Result<SetBucketReplicationResponse>, so the explicit SetBucketReplicationResponse type makes resp.error() invalid. This matches the same pattern as DeleteObjectLockConfig.cc.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/SetBucketReplication.cc` around lines 50 - 58, The
SetBucketReplication example is using the concrete response type for resp, but
client.SetBucketReplication(args) returns a Result, so the explicit type makes
resp.error() invalid. Update the SetBucketReplicationResponse handling in
SetBucketReplication to use auto for resp, matching the pattern used in
DeleteObjectLockConfig, so the success check and error() call work correctly.
examples/GetBucketReplication.cc (2)

20-50: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Replace the encryption example with the replication API.
examples/GetBucketReplication.cc still builds GetBucketEncryptionArgs, calls client.GetBucketEncryption(args), and prints encryption fields, so the example does not demonstrate bucket replication at all. Developers will get the wrong API shape from this file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/GetBucketReplication.cc` around lines 20 - 50, The example is still
using the encryption API instead of replication, so update the logic in main to
use the bucket replication types and call the replication method on
minio::s3::Client. Replace GetBucketEncryptionArgs/GetBucketEncryptionResponse
and the encryption-specific field printing with the corresponding
GetBucketReplicationArgs/GetBucketReplicationResponse and replication output so
this file correctly demonstrates bucket replication.

36-47: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Restore the replication API call here GetBucketReplication.cc still uses GetBucketEncryptionArgs, GetBucketEncryptionResponse, and client.GetBucketEncryption(args), so this example isn’t exercising replication yet.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/GetBucketReplication.cc` around lines 36 - 47, The
GetBucketReplication example is still wired to the encryption API instead of
replication. Update the GetBucketReplication.cc example to use the
replication-specific types and call path in place of GetBucketEncryptionArgs,
GetBucketEncryptionResponse, and client.GetBucketEncryption(args), and adjust
the response handling to print replication-related fields via the corresponding
replication response object so the example exercises the replication API.
examples/GetBucketNotification.cc (1)

36-45: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Use the result wrapper for GetBucketNotification. client.GetBucketNotification(args) needs to be stored as auto so resp.error() and resp->config match the returned result type; GetBucketNotificationResponse resp = ... leaves the response/payload access mismatched.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/GetBucketNotification.cc` around lines 36 - 45,
`GetBucketNotification` is being stored as the concrete response type instead of
the result wrapper, which makes `resp.error()` and payload access inconsistent.
Update the `GetBucketNotification` call site to keep the returned result in
`auto resp` so the success path uses `resp->config` and the failure path uses
`resp.error()` against the same wrapper type. Use the `GetBucketNotification`
symbol and the `resp` handling in `main` to locate and align the access pattern.
examples/GetBucketEncryption.cc (1)

36-47: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use Result<GetBucketEncryptionResponse> here
client.GetBucketEncryption(args) returns Result<GetBucketEncryptionResponse>, so the current GetBucketEncryptionResponse resp = ... declaration makes both if (resp) and resp.error() invalid. Switch this to auto resp = client.GetBucketEncryption(args); and access the payload with resp->config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/GetBucketEncryption.cc` around lines 36 - 47,
`GetBucketEncryptionResponse resp = client.GetBucketEncryption(args);` is using
the wrong type for `Client::GetBucketEncryption`, which returns
`Result<GetBucketEncryptionResponse>`; update the variable in
`GetBucketEncryption` to keep the result wrapper (for example via `auto resp =
...`) so `if (resp)` and `resp.error()` are valid, and then read the response
fields through the result payload using `resp->config` instead of direct member
access.
examples/SetObjectLockConfig.cc (1)

38-47: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use auto for resp here SetObjectLockConfig returns Result<SetObjectLockConfigResponse>, so the explicit SetObjectLockConfigResponse declaration makes resp.error() invalid.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/SetObjectLockConfig.cc` around lines 38 - 47, `SetObjectLockConfig`
returns a Result wrapper, so the explicit `SetObjectLockConfigResponse` type on
`resp` in `SetObjectLockConfig` is wrong and makes `resp.error()` invalid.
Update the `resp` declaration to use type deduction with `auto` so the Result
type is preserved, and keep the existing success/error handling in the `if
(resp)` block unchanged.
examples/SetBucketVersioning.cc (1)

37-46: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Use auto for resp here. client.SetBucketVersioning(args) returns Result<SetBucketVersioningResponse>, so the explicit SetBucketVersioningResponse declaration makes resp.error() invalid.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/SetBucketVersioning.cc` around lines 37 - 46, Use auto for resp in
SetBucketVersioning so it keeps the Result<SetBucketVersioningResponse> type
returned by client.SetBucketVersioning(args); the explicit
minio::s3::SetBucketVersioningResponse declaration breaks resp.error() in the
success/failure handling. Update the resp declaration in SetBucketVersioning
accordingly and keep the existing if (resp) / resp.error().String() logic
unchanged.
examples/GetObjectLockConfig.cc (1)

36-57: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the Result type here
client.GetObjectLockConfig(args) returns Result<GetObjectLockConfigResponse>, but GetObjectLockConfigResponse is just a plain struct. if (resp) and resp.error() only work on the Result, so this declaration should be auto resp = ... or Result<GetObjectLockConfigResponse> resp = ....

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/GetObjectLockConfig.cc` around lines 36 - 57, The response from
client.GetObjectLockConfig(args) is being stored as the plain
GetObjectLockConfigResponse struct, but the subsequent if (resp) and
resp.error() logic requires the Result<GetObjectLockConfigResponse> wrapper.
Update the declaration in GetObjectLockConfig.main so resp is declared as auto
or as minio::s3::Result<GetObjectLockConfigResponse>, then keep the existing
success/error handling unchanged.
examples/GetBucketVersioning.cc (1)

36-44: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use Result<GetBucketVersioningResponse> hereclient.GetBucketVersioning(args) returns minio::Result<GetBucketVersioningResponse>, so binding it to plain minio::s3::GetBucketVersioningResponse drops the .error() path and won’t compile. auto resp = ... (or the explicit minio::Result<...>) matches the API.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/GetBucketVersioning.cc` around lines 36 - 44, The
GetBucketVersioning example is binding the return value of
client.GetBucketVersioning(args) to minio::s3::GetBucketVersioningResponse,
which drops the error-handling wrapper and breaks the resp.error() path. Update
the response variable in GetBucketVersioning to use
minio::Result<GetBucketVersioningResponse> or auto so it matches the API and
preserves both success and error handling.
examples/GetObjectRetention.cc (1)

40-49: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Use resp->... when reading the GetObjectRetentionResponse.
resp is a Result<GetObjectRetentionResponse> (tl::expected), so resp.retention_mode and resp.retain_until_date won’t compile. Use pointer access on the wrapped value instead.

🐛 Proposed fix
   if (resp) {
     std::cout << "Retention Mode: "
-              << minio::s3::RetentionModeToString(resp.retention_mode)
+              << minio::s3::RetentionModeToString(resp->retention_mode)
               << std::endl;
     std::cout << "Retain Until Date: "
-              << resp.retain_until_date.ToHttpHeaderValue() << std::endl;
+              << resp->retain_until_date.ToHttpHeaderValue() << std::endl;
   } else {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/GetObjectRetention.cc` around lines 40 - 49, In
GetObjectRetention.cc, the code is treating GetObjectRetentionResponse as if it
were the Result wrapper itself; update the success branch to access the wrapped
response via resp->... instead of resp.retention_mode and
resp.retain_until_date. Use the GetObjectRetentionResponse result value returned
by the response object consistently, and keep the error branch using
resp.error().String() for the failure case.
examples/StatObject.cc (1)

40-76: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the remaining resp field accesses

resp is a Result<StatObjectResponse>, so the remaining resp. reads (last_modified, retention_mode, retention_retain_until_date, legal_hold, delete_marker) won’t compile; switch them to resp->... for consistency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/StatObject.cc` around lines 40 - 76, The remaining `resp` accesses
in `StatObject` are using dot syntax on a `Result<StatObjectResponse>` and will
not compile. Update the `last_modified`, `retention_mode`,
`retention_retain_until_date`, `legal_hold`, and `delete_marker` reads in the
`if (resp)` block to use `resp->...` consistently, matching the existing
`version_id`, `etag`, `size`, and `user_metadata` access style.
examples/GetPresignedPostFormData.cc (1)

43-53: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use resp->form_data here
client.GetPresignedPostFormData(policy) returns Result<GetPresignedPostFormDataResponse>, so resp.form_data won’t compile. Use resp->form_data in the success branch.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/GetPresignedPostFormData.cc` around lines 43 - 53, The success
branch in GetPresignedPostFormData is accessing the Result object incorrectly;
client.GetPresignedPostFormData(policy) returns a
Result<GetPresignedPostFormDataResponse>, so use the dereferenced response when
iterating form_data. Update the resp handling in the example to read form_data
from the successful response object (the one checked by if (resp)) and keep the
error branch using resp.error().String() unchanged.
examples/ListenBucketNotification.cc (1)

44-51: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use auto for ListenBucketNotification

ListenBucketNotification returns Result<ListenBucketNotificationResponse>, so ListenBucketNotificationResponse resp = ... is a type mismatch and won’t compile. Keep this as auto resp = client.ListenBucketNotification(args); so resp.error() stays valid.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/ListenBucketNotification.cc` around lines 44 - 51, The
ListenBucketNotification example is using the wrong variable type, since
ListenBucketNotification returns a Result<ListenBucketNotificationResponse>
rather than a raw ListenBucketNotificationResponse. Update the declaration in
ListenBucketNotification to use auto for the result returned by
client.ListenBucketNotification(args), so the existing resp.error() handling
remains valid and the code compiles.
examples/IsObjectLegalHoldEnabled.cc (1)

37-45: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the Result<IsObjectLegalHoldEnabledResponse> form here
client.IsObjectLegalHoldEnabled(args) returns Result<IsObjectLegalHoldEnabledResponse>, so IsObjectLegalHoldEnabledResponse resp = ... and resp.enabled don’t match the API. Switch to auto resp = ..., read resp->enabled, and keep resp.error() for the failure path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/IsObjectLegalHoldEnabled.cc` around lines 37 - 45, The example is
using the wrong return type for client.IsObjectLegalHoldEnabled(args), so update
IsObjectLegalHoldEnabledResponse resp to the
Result<IsObjectLegalHoldEnabledResponse> form by using auto resp = ...; then
access the success value through resp->enabled instead of resp.enabled, and keep
the existing resp.error().String() handling in the failure branch.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/GetBucketLifecycle.cc`:
- Around line 36-44: `GetBucketLifecycle` is using the expected payload
incorrectly in the success branch. Update the response handling in
`GetBucketLifecycle` to access the lifecycle configuration through
`resp->config` (or `(*resp).config`) instead of `resp.config`, while leaving the
`resp.error()` usage in the failure branch unchanged.

In `@examples/GetBucketPolicy.cc`:
- Around line 36-43: The response handling in GetBucketPolicy uses the
Result<GetBucketPolicyResponse> object directly instead of the contained
response; update the successful branch in GetBucketPolicy to access the policy
through the dereferenced result object, matching the pattern used in
GetBucketLifecycle. Keep the error branch unchanged, and make sure the fix is
applied wherever resp is treated as a Result so members are read from the
underlying response rather than from resp itself.

---

Outside diff comments:
In `@examples/DeleteBucketEncryption.cc`:
- Around line 36-44: The delete-bucket-encryption example is using the concrete
response type instead of the returned Result type, which will not compile.
Update the response declaration in DeleteBucketEncryptionResponse handling to
use auto with client.DeleteBucketEncryption(args), matching the other examples
and keeping the existing success/error handling unchanged.

In `@examples/DeleteBucketLifecycle.cc`:
- Around line 36-46: The DeleteBucketLifecycle example is using the response
type directly instead of the Result wrapper returned by
Client::DeleteBucketLifecycle. Update the resp declaration in
DeleteBucketLifecycle.cc to use auto or an explicit
Result<DeleteBucketLifecycleResponse>, then keep the existing success/error
handling against the Result object so resp.error() compiles correctly.

In `@examples/DeleteBucketNotification.cc`:
- Around line 36-46: The DeleteBucketNotification example is declaring the
return value as the concrete response type instead of the Result wrapper
returned by client.DeleteBucketNotification(args), which breaks compilation and
prevents access to error(). Update the resp declaration in
DeleteBucketNotification to use auto so it preserves the
Result<DeleteBucketNotificationResponse> type, and keep the existing
success/error handling logic unchanged.

In `@examples/DeleteBucketReplication.cc`:
- Around line 36-46: The response variable in the DeleteBucketEncryption example
is using an explicit concrete type, but it should match the other examples and
use auto instead. Update the resp declaration in the DeleteBucketEncryption
example to use auto, keeping the existing call to
client.DeleteBucketEncryption(args) and the subsequent response handling
unchanged.

In `@examples/DeleteObjectLockConfig.cc`:
- Around line 36-45: The DeleteObjectLockConfig example is using the concrete
response type for the result of client.DeleteObjectLockConfig(args), which
strips the Result wrapper and prevents access to resp.error() in the failure
branch. Update the declaration in DeleteObjectLockConfig example to use auto for
the DeleteObjectLockConfigConfig/response result so it preserves the
Result<DeleteObjectLockConfigResponse> type, matching the other updated examples
and keeping both the success and error handling paths valid.

In `@examples/DisableObjectLegalHold.cc`:
- Around line 37-46: The DisableObjectLegalHold example is declaring the result
as DisableObjectLegalHoldResponse, but client.DisableObjectLegalHold(args)
returns a Result wrapper, so the later resp.error() access is invalid. Update
the variable in DisableObjectLegalHold.cc to use auto for the
DisableObjectLegalHold call result, matching the pattern used in the other
examples, and keep the existing success/error handling unchanged.

In `@examples/EnableObjectLegalHold.cc`:
- Around line 37-46: The response variable in EnableObjectLegalHold should be
declared with auto rather than the concrete EnableObjectLegalHoldResponse type,
since the returned result object is what supports both the boolean check and
error() access. Update the declaration in the EnableObjectLegalHold example to
preserve the client.EnableObjectLegalHold(args) return type, then keep the
existing if (resp) / resp.error() handling unchanged.

In `@examples/GetBucketEncryption.cc`:
- Around line 36-47: `GetBucketEncryptionResponse resp =
client.GetBucketEncryption(args);` is using the wrong type for
`Client::GetBucketEncryption`, which returns
`Result<GetBucketEncryptionResponse>`; update the variable in
`GetBucketEncryption` to keep the result wrapper (for example via `auto resp =
...`) so `if (resp)` and `resp.error()` are valid, and then read the response
fields through the result payload using `resp->config` instead of direct member
access.

In `@examples/GetBucketNotification.cc`:
- Around line 36-45: `GetBucketNotification` is being stored as the concrete
response type instead of the result wrapper, which makes `resp.error()` and
payload access inconsistent. Update the `GetBucketNotification` call site to
keep the returned result in `auto resp` so the success path uses `resp->config`
and the failure path uses `resp.error()` against the same wrapper type. Use the
`GetBucketNotification` symbol and the `resp` handling in `main` to locate and
align the access pattern.

In `@examples/GetBucketReplication.cc`:
- Around line 20-50: The example is still using the encryption API instead of
replication, so update the logic in main to use the bucket replication types and
call the replication method on minio::s3::Client. Replace
GetBucketEncryptionArgs/GetBucketEncryptionResponse and the encryption-specific
field printing with the corresponding
GetBucketReplicationArgs/GetBucketReplicationResponse and replication output so
this file correctly demonstrates bucket replication.
- Around line 36-47: The GetBucketReplication example is still wired to the
encryption API instead of replication. Update the GetBucketReplication.cc
example to use the replication-specific types and call path in place of
GetBucketEncryptionArgs, GetBucketEncryptionResponse, and
client.GetBucketEncryption(args), and adjust the response handling to print
replication-related fields via the corresponding replication response object so
the example exercises the replication API.

In `@examples/GetBucketVersioning.cc`:
- Around line 36-44: The GetBucketVersioning example is binding the return value
of client.GetBucketVersioning(args) to minio::s3::GetBucketVersioningResponse,
which drops the error-handling wrapper and breaks the resp.error() path. Update
the response variable in GetBucketVersioning to use
minio::Result<GetBucketVersioningResponse> or auto so it matches the API and
preserves both success and error handling.

In `@examples/GetObjectLockConfig.cc`:
- Around line 36-57: The response from client.GetObjectLockConfig(args) is being
stored as the plain GetObjectLockConfigResponse struct, but the subsequent if
(resp) and resp.error() logic requires the Result<GetObjectLockConfigResponse>
wrapper. Update the declaration in GetObjectLockConfig.main so resp is declared
as auto or as minio::s3::Result<GetObjectLockConfigResponse>, then keep the
existing success/error handling unchanged.

In `@examples/GetObjectRetention.cc`:
- Around line 40-49: In GetObjectRetention.cc, the code is treating
GetObjectRetentionResponse as if it were the Result wrapper itself; update the
success branch to access the wrapped response via resp->... instead of
resp.retention_mode and resp.retain_until_date. Use the
GetObjectRetentionResponse result value returned by the response object
consistently, and keep the error branch using resp.error().String() for the
failure case.

In `@examples/GetPresignedPostFormData.cc`:
- Around line 43-53: The success branch in GetPresignedPostFormData is accessing
the Result object incorrectly; client.GetPresignedPostFormData(policy) returns a
Result<GetPresignedPostFormDataResponse>, so use the dereferenced response when
iterating form_data. Update the resp handling in the example to read form_data
from the successful response object (the one checked by if (resp)) and keep the
error branch using resp.error().String() unchanged.

In `@examples/IsObjectLegalHoldEnabled.cc`:
- Around line 37-45: The example is using the wrong return type for
client.IsObjectLegalHoldEnabled(args), so update
IsObjectLegalHoldEnabledResponse resp to the
Result<IsObjectLegalHoldEnabledResponse> form by using auto resp = ...; then
access the success value through resp->enabled instead of resp.enabled, and keep
the existing resp.error().String() handling in the failure branch.

In `@examples/ListenBucketNotification.cc`:
- Around line 44-51: The ListenBucketNotification example is using the wrong
variable type, since ListenBucketNotification returns a
Result<ListenBucketNotificationResponse> rather than a raw
ListenBucketNotificationResponse. Update the declaration in
ListenBucketNotification to use auto for the result returned by
client.ListenBucketNotification(args), so the existing resp.error() handling
remains valid and the code compiles.

In `@examples/SelectObjectContent.cc`:
- Around line 56-64: The SelectObjectContent example declares resp as the
concrete SelectObjectContentResponse even though
client.SelectObjectContent(args) returns a Result<SelectObjectContentResponse>,
which causes a compile-time type mismatch. Update the
SelectObjectContentResponse resp declaration in SelectObjectContent to use auto
so the result type is inferred correctly, while keeping the existing
success/error handling logic unchanged.

In `@examples/SetBucketReplication.cc`:
- Around line 50-58: The SetBucketReplication example is using the concrete
response type for resp, but client.SetBucketReplication(args) returns a Result,
so the explicit type makes resp.error() invalid. Update the
SetBucketReplicationResponse handling in SetBucketReplication to use auto for
resp, matching the pattern used in DeleteObjectLockConfig, so the success check
and error() call work correctly.

In `@examples/SetBucketVersioning.cc`:
- Around line 37-46: Use auto for resp in SetBucketVersioning so it keeps the
Result<SetBucketVersioningResponse> type returned by
client.SetBucketVersioning(args); the explicit
minio::s3::SetBucketVersioningResponse declaration breaks resp.error() in the
success/failure handling. Update the resp declaration in SetBucketVersioning
accordingly and keep the existing if (resp) / resp.error().String() logic
unchanged.

In `@examples/SetObjectLockConfig.cc`:
- Around line 38-47: `SetObjectLockConfig` returns a Result wrapper, so the
explicit `SetObjectLockConfigResponse` type on `resp` in `SetObjectLockConfig`
is wrong and makes `resp.error()` invalid. Update the `resp` declaration to use
type deduction with `auto` so the Result type is preserved, and keep the
existing success/error handling in the `if (resp)` block unchanged.

In `@examples/StatObject.cc`:
- Around line 40-76: The remaining `resp` accesses in `StatObject` are using dot
syntax on a `Result<StatObjectResponse>` and will not compile. Update the
`last_modified`, `retention_mode`, `retention_retain_until_date`, `legal_hold`,
and `delete_marker` reads in the `if (resp)` block to use `resp->...`
consistently, matching the existing `version_id`, `etag`, `size`, and
`user_metadata` access style.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fd049af4-4ae9-4cf7-be9e-b36f90260ee5

📥 Commits

Reviewing files that changed from the base of the PR and between a32a510 and c50e502.

📒 Files selected for processing (52)
  • examples/BucketExists.cc
  • examples/ComposeObject.cc
  • examples/CopyObject.cc
  • examples/DeleteBucketEncryption.cc
  • examples/DeleteBucketLifecycle.cc
  • examples/DeleteBucketNotification.cc
  • examples/DeleteBucketPolicy.cc
  • examples/DeleteBucketReplication.cc
  • examples/DeleteBucketTags.cc
  • examples/DeleteObjectLockConfig.cc
  • examples/DeleteObjectTags.cc
  • examples/DisableObjectLegalHold.cc
  • examples/DownloadObject.cc
  • examples/EnableObjectLegalHold.cc
  • examples/GetBucketEncryption.cc
  • examples/GetBucketLifecycle.cc
  • examples/GetBucketNotification.cc
  • examples/GetBucketPolicy.cc
  • examples/GetBucketReplication.cc
  • examples/GetBucketTags.cc
  • examples/GetBucketVersioning.cc
  • examples/GetObject.cc
  • examples/GetObjectLockConfig.cc
  • examples/GetObjectProgress.cc
  • examples/GetObjectRetention.cc
  • examples/GetObjectTags.cc
  • examples/GetPresignedObjectUrl.cc
  • examples/GetPresignedPostFormData.cc
  • examples/GetPutRDMA.cc
  • examples/IsObjectLegalHoldEnabled.cc
  • examples/ListBuckets.cc
  • examples/ListObjects.cc
  • examples/ListenBucketNotification.cc
  • examples/MakeBucket.cc
  • examples/PutObject.cc
  • examples/PutObjectProgress.cc
  • examples/RemoveBucket.cc
  • examples/RemoveObject.cc
  • examples/RemoveObjects.cc
  • examples/SelectObjectContent.cc
  • examples/SetBucketEncryption.cc
  • examples/SetBucketLifecycle.cc
  • examples/SetBucketNotification.cc
  • examples/SetBucketPolicy.cc
  • examples/SetBucketReplication.cc
  • examples/SetBucketTags.cc
  • examples/SetBucketVersioning.cc
  • examples/SetObjectLockConfig.cc
  • examples/SetObjectRetention.cc
  • examples/SetObjectTags.cc
  • examples/StatObject.cc
  • examples/UploadObject.cc

Comment thread examples/GetBucketLifecycle.cc
Comment thread examples/GetBucketPolicy.cc
@harshavardhana harshavardhana merged commit 3d21189 into minio:main Jul 7, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants