Skip to content

Add commit info to partition exports table#1832

Open
arthurpassos wants to merge 26 commits into
antalya-26.3from
expand-replicated-partition-exports-columns
Open

Add commit info to partition exports table#1832
arthurpassos wants to merge 26 commits into
antalya-26.3from
expand-replicated-partition-exports-columns

Conversation

@arthurpassos

@arthurpassos arthurpassos commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Changelog category (leave one):

  • Improvement

Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):

Add Iceberg metadata file paths and data file paths to the system.replicated_partition_exports to improve observability and debugging. Closes #1832

Also replaces clickhouse snowflakeid implementation with uuidv4

Documentation entry for user-facing changes

...

CI/CD Options

Exclude tests:

  • Fast test
  • Integration Tests
  • Stateless tests
  • Stateful tests
  • Performance tests
  • All with ASAN
  • All with TSAN
  • All with MSAN
  • All with UBSAN
  • All with Coverage
  • All with Aarch64
  • All Regression
  • Disable CI Cache

Regression jobs to run:

  • Fast suites (mostly <1h)
  • Aggregate Functions (2h)
  • Alter (1.5h)
  • Benchmark (30m)
  • ClickHouse Keeper (1h)
  • Iceberg (2h)
  • LDAP (1h)
  • Parquet (1.5h)
  • RBAC (1.5h)
  • SSL Server (1h)
  • S3 (2h)
  • S3 Export (2h)
  • Swarms (30m)
  • Tiered Storage (2h)

@arthurpassos arthurpassos added antalya-26.3 port-antalya PRs to be ported to all new Antalya releases antalya labels May 25, 2026
@arthurpassos

Copy link
Copy Markdown
Collaborator Author

@codex review

@github-actions

github-actions Bot commented May 25, 2026

Copy link
Copy Markdown

Workflow [PR], commit [928cc25]

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a9022d641

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1900 to +1907
LOG_INFO(log,
"Export transaction {} already committed, skipping re-commit",
transaction_id);
return;
/// Empty commit info: paths produced by the original commit are not recoverable
/// here without re-reading the snapshot. ExportPartitionUtils::commit only
/// writes the commit_info znode when this struct is non-empty, so the original
/// committer's record (if any) is preserved.
return {};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return commit info for already-committed recovery path

When isExportPartitionTransactionAlreadyCommitted is true here, the function returns an empty ExportPartitionCommitInfo, which makes ExportPartitionUtils::commit skip writing <export-entry>/commit_info and only flip status to COMPLETED. In the common recovery scenario (snapshot committed previously, then retried before ZooKeeper was updated), this leaves committed_* fields permanently empty and contradicts the new observability behavior/documentation that expects a visible marker for already-committed retries.

Useful? React with 👍 / 👎.

Comment on lines +857 to +858
assert committed_metadata_file == "<committed in a previous run, paths unavailable>", (
f"Expected sentinel in committed_metadata_file for already-committed retry, got: {committed_metadata_file!r}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Fix sentinel expectation in post-publish failpoint test

This assertion is inconsistent with the implementation under iceberg_writes_post_publish_throw: that failpoint is ONCE, and the published catch path now returns real file paths (storage_metadata_name, manifest list, manifest file), so committed_metadata_file should be a metadata path, not the "previous run" sentinel. As written, the test will fail despite correct behavior and can block CI.

Useful? React with 👍 / 👎.

@arthurpassos

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ianton-ru

Copy link
Copy Markdown

AI audit note: This review comment was generated by AI (gpt-5.3-codex).

Audit update for PR #1832 (Add commit info to partition exports table):

Confirmed defects

Medium: commit_info serialization failure can block COMPLETED transition

Impact: A successful destination commit (Iceberg snapshot or object-storage marker) can remain stuck in PENDING (or require later recovery) if commit-info JSON generation throws before ZooKeeper /status is flipped to COMPLETED.

Anchor: src/Storages/MergeTree/ExportPartitionUtils.cpp / ExportPartitionUtils::commit and ExportReplicatedMergeTreePartitionCommitInfoEntry::toJsonString

Trigger: Any exception thrown by ExportReplicatedMergeTreePartitionCommitInfoEntry::toJsonString (it explicitly enables std::ios::failbit exceptions) while destination_commit_info is non-empty.

Why defect: The new observability side-effect (JSON stringify) is now on the critical path of the state transition; a stringify exception aborts the function before the status update, changing behavior from “commit then mark completed” to “commit then throw”.

Fix direction (short): Make commit_info persistence best-effort: wrap toJsonString + tryMulti in try/catch and always fall back to status-only trySet on any exception.

Regression test direction (short): Add a failpoint (or targeted fault injection) that throws during commit_info serialization and assert the task still reaches COMPLETED.

Evidence

Serialization enables stream exceptions:

std::string toJsonString() const
{
    Poco::JSON::Object json;
    json.set("iceberg_metadata_file", iceberg_metadata_file);
    // ...
    std::ostringstream oss;
    oss.exceptions(std::ios::failbit);
    Poco::JSON::Stringifier::stringify(json, oss);
    return oss.str();
}

toJsonString is called before the status flip in the new “atomic commit_info + COMPLETED” multi-op; an exception here prevents reaching the fallback status-only set:

if (!destination_commit_info.empty())
{
    ExportReplicatedMergeTreePartitionCommitInfoEntry commit_info_entry { /* ... */ };
    const std::string commit_info_path = fs::path(entry_path) / "commit_info";

    Coordination::Requests ops;
    ops.emplace_back(zkutil::makeCreateRequest(commit_info_path, commit_info_entry.toJsonString(), zkutil::CreateMode::Persistent));
    ops.emplace_back(zkutil::makeSetRequest(status_path, completed_name, -1));
    // ...
    if (rc == Coordination::Error::ZOK)
    {
        LOG_INFO(log, "ExportPartition: Marked export as completed and persisted commit_info");
        return;
    }
    // fall through to status-only set on ZNODEEXISTS / other errors
}

Coverage summary

Item Detail
Scope reviewed ZK state machine around export task completion (processed/*, status, new commit_info), commit idempotency behavior for Iceberg and plain object storage, in-memory mirror → system.replicated_partition_exports, and integration tests added/updated in the patch.
Categories failed Exception-safety / partial-update (new JSON serialization on completion critical path).
Categories passed State-transition consistency (status + commit_info via tryMulti with status-only fallback), idempotency signaling (Iceberg “already committed” sentinel; object-storage marker path surfaced even if pre-existing), concurrency/interleaving (peer-written commit_info handled via ZNODEEXISTS → status-only set), best-effort ZK mirroring semantics (poll-time refresh; no extra ZK reads on system-table query).
Assumptions/limits Audit is based on the PR’s public patch (.patch) and static reasoning (no local build/test execution).

### Commit info columns

These columns surface paths produced by the destination storage during commit, so it is possible to inspect what was written without consulting the destination directly:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Description for destination_file_paths column is missing.

/// files and reaching this point, the task still completes via the recovery
/// path but commit_info will be absent. Recovering commit_info from the
/// live Iceberg snapshot in that case is a possible future enhancement.
const std::string status_path = fs::path(entry_path) / "status";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

AI thinks that exception in the block below can breaks commit transaction.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't think that is totally true. here's what can happen:

once we commit to iceberg, we need to mark it as completed in zookeeper. If the code that creates the commit info throws, we don't mark it as completed in zookeeper and it remains in pending state. In the next scheduler tick, we'll try to commit it again, and we'll notice it has already been committed. In that case, we just mark it as completed. It won't remain in pending forever as far as I can tell

@arthurpassos
arthurpassos requested a review from ianton-ru May 29, 2026 17:03
ianton-ru
ianton-ru previously approved these changes May 29, 2026

@ianton-ru ianton-ru 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.

LGTM

@DimensionWieldr

Copy link
Copy Markdown
Collaborator

@arthurpassos Looks like build is still failing. Maybe check IcebergMetadata.cpp?
Build jobs fail with:

IcebergMetadata.cpp:1815: error: use of undeclared identifier 'storage_metadata_name'
  IcebergMetadata.cpp:1817: error: use of undeclared identifier 'storage_manifest_entry_name'
  IcebergMetadata.cpp:1831: error: use of undeclared identifier 'storage_metadata_name'
  IcebergMetadata.cpp:1833: error: use of undeclared identifier 'storage_manifest_entry_name'

@DimensionWieldr

DimensionWieldr commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

Failing integration tests (new fails in PR) are fixed in other PRs. Regression fails unrelated.

Manually tested, no issues. (Auto-tests will be added later.)

AI audit returned no major blockers.

LGTM

@DimensionWieldr DimensionWieldr added the verified Approved for release label Jun 1, 2026
@DimensionWieldr DimensionWieldr removed the verified Approved for release label Jun 2, 2026
@DimensionWieldr

Copy link
Copy Markdown
Collaborator

Following integration tests and one stateless test are failing with recent changes (new fails in this PR).

test_export_replicated_mt_partition_to_iceberg/test.py::test_failure_is_logged_in_system_table
test_export_replicated_mt_partition_to_iceberg/test.py::test_inject_short_living_failures
test_export_replicated_mt_partition_to_iceberg/test.py::test_post_publish_exception_preserves_snapshot
test_quorum_inserts_parallel/test.py::test_parallel_quorum_actually_parallel
test_storage_iceberg_with_spark/test_export_partition_iceberg.py::test_idempotency_after_commit_crash
test_storage_iceberg_with_spark/test_export_partition_iceberg_catalog.py::test_catalog_idempotent_retry
test_export_replicated_mt_partition_to_iceberg/test.py::test_export_task_timeout_kills_stuck_pending_task
test_export_replicated_mt_partition_to_iceberg/test.py::test_failure_is_logged_in_system_table
test_export_replicated_mt_partition_to_iceberg/test.py::test_inject_short_living_failures
test_export_replicated_mt_partition_to_iceberg/test.py::test_post_publish_exception_preserves_snapshot

00157_cache_dictionary

@svb-alt svb-alt added the roadmap Key features and improvements for Antalya project label Jun 7, 2026
@arthurpassos

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76f1cd7290

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +821 to +824
if (auto fetched_commit_info = readCommitInfo(
zk, fs::path(storage.zookeeper_path) / "exports" / key, key, log))
{
it->commit_info = std::move(fetched_commit_info);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Retry commit_info reads after transient misses

When the status-change handler sees COMPLETED, readCommitInfo returns nullopt not only when the znode is genuinely absent but also on a transient Keeper read failure. This branch then silently skips the assignment and later stores the entry as COMPLETED, so subsequent polls no longer retry the read because their status_changed check is false; the committed_* columns can remain empty for this in-memory entry until restart even though <export-entry>/commit_info exists. Retry while a completed entry has no local commit_info, or avoid treating a transient miss as final.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Should be fixed by 1b6ed4e

@arthurpassos

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 54799a7e82

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +581 to +582
local_entry->last_exception_per_replica = std::move(last_exception_per_replica);
local_entry->destination_file_paths_per_part = std::move(destination_file_paths_per_part);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve cached export details on empty ZK reads

When an existing task is polled, these assignments overwrite the in-memory mirror even when the ZooKeeper reads returned an empty map because tryGetChildren failed or a child disappeared concurrently; the new readDestinationFilePathsPerPart comment explicitly says callers must skip assignment in that case, and readLastExceptionPerReplica has the same lenient behavior. Under a transient Keeper hiccup, a completed export that already had exceptions or destination paths will briefly lose last_exception_per_replica, exception_count, and destination_file_paths from system.replicated_partition_exports, which is the table this change is trying to improve for debugging.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Should be fixed by 5f67e46

@arthurpassos

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5f67e46302

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Storages/MergeTree/ExportPartitionManifestUpdatingTask.cpp Outdated
@arthurpassos

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e30bdeb525

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Storages/MergeTree/ExportPartitionManifestUpdatingTask.cpp Outdated
This reverts commit e30bdeb.
@arthurpassos

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c9d0bc9dd1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +548 to +549
auto destination_file_paths_per_part = readDestinationFilePathsPerPart(
zk, fs::path(entry_path), key, log);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid polling processed leaves after terminal states

When a local entry is already COMPLETED/FAILED/KILLED, this call still lists /processed and batch-gets every processed part on every manifest-updater poll. Completed export znodes are kept for system.replicated_partition_exports and removal is only done on force-overwrite, so a table with historical exports or large partitions will keep generating O(total processed parts) Keeper reads indefinitely. Please skip this refresh for terminal entries once the in-memory map is populated, while still reading it for new entries and status transitions.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I opt for ignoring this optimization for now

@arthurpassos
arthurpassos requested a review from ianton-ru July 13, 2026 13:47
@arthurpassos

Copy link
Copy Markdown
Collaborator Author

I am tyring to debug the flaky failures on CICD - not easy tho.

@arthurpassos

Copy link
Copy Markdown
Collaborator Author

I am tyring to debug the flaky failures on CICD - not easy tho.

Surprisingly enough (and with tons of help from AI), it seems like the transaction ids are colliding. Snowflakeid does not seem to be that reliable.

continue;
}

if (response.error != Coordination::Error::ZOK)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why not add record to log here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I am actually re-thinking this err handling. Your opinion would be appreciated. This fetch operation, among others, is done in the background to sync the export manifests. ClickHouse keeps an in-memory list that is a mirror of zookeeper.

When the user queries system.replicated_partition_exports, he queries the in-memory mirror, no zookeeper. If during the background sync the query for part_2 destination file paths fails, with the current error handling mechanism, we'll get something like:

part_1: ['f1.parquet', 'f2.parquet']
part_2: []
part_3: ['f5.parquet']

even though part_2 has already exported files.

At a second glance, it would be better if we could warn the user something went wrong during the background sync and the data might be incomplete.

Initially, I thought of introducing a marker / poison pill:

part_2: ['ERR DURING SYNC']

But I also see a different pattern for other zookeeper backed tables like system.replicas where a there is a column called zookeeper_exception.

The former is easy to implement. The latter requires some sort of refactoring.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I think option n2 is the best solution, especially if I can flat out the zookeeper schema to reduce the chances of this happening.

At the same time, option n1 is easier to implement and I think I'll go for this one in this iteration. Especially because implementing option n2 could be backwards incompatible.


auto fetched = readLastExceptionPerReplica(
zk, fs::path(storage.zookeeper_path) / "exports" / key, key, storage.log.load());
zk, fs::path(storage.zookeeper_path) / "exports" / key, key, log);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The same path is made in lines 829 and 840 below, better to make it only once.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done

@DimensionWieldr

DimensionWieldr commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Hmm, failed to build for some reason: https://altinity-build-artifacts.s3.amazonaws.com/json.html?PR=1832&sha=a785899938fc7cef4f62ec0774c116f5538f058b&name_0=PR&name_1=Fast%20test

Some logs:

  879 |                 it->destination_file_paths_per_part = std::move(destination_file_paths_per_part);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ubuntu/_work/ClickHouse/ClickHouse/contrib/llvm-project/libcxx/include/map:975:30: note: candidate function not viable: no known conversion from '__libcpp_remove_reference_t<std::optional<std::map<std::string, std::vector<std::string, std::allocator<std::string>>, std::less<std::string>, std::allocator<std::pair<const std::string, std::vector<std::string, std::allocator<std::string>>>>>> &>' (aka 'std::optional<std::map<std::string, std::vector<std::string>>>') to 'const map<std::string, std::vector<std::string>>' for 1st argument
  975 |   _LIBCPP_HIDE_FROM_ABI map& operator=(const map& __m) = default;
      |                              ^         ~~~~~~~~~~~~~~
/home/ubuntu/_work/ClickHouse/ClickHouse/contrib/llvm-project/libcxx/include/map:983:30: note: candidate function not viable: no known conversion from '__libcpp_remove_reference_t<std::optional<std::map<std::string, std::vector<std::string, std::allocator<std::string>>, std::less<std::string>, std::allocator<std::pair<const std::string, std::vector<std::string, std::allocator<std::string>>>>>> &>' (aka 'std::optional<std::map<std::string, std::vector<std::string>>>') to 'map<std::string, std::vector<std::string>>' for 1st argument
  983 |   _LIBCPP_HIDE_FROM_ABI map& operator=(map&& __m) noexcept(is_nothrow_move_assignable<__base>::value) = default;
      |                              ^         ~~~~~~~~~
/home/ubuntu/_work/ClickHouse/ClickHouse/contrib/llvm-project/libcxx/include/map:1000:30: note: candidate function not viable: no known conversion from '__libcpp_remove_reference_t<std::optional<std::map<std::string, std::vector<std::string, std::allocator<std::string>>, std::less<std::string>, std::allocator<std::pair<const std::string, std::vector<std::string, std::allocator<std::string>>>>>> &>' (aka 'std::optional<std::map<std::string, std::vector<std::string>>>') to 'initializer_list<value_type>' (aka 'initializer_list<pair<const std::string, std::vector<std::string, std::allocator<std::string>>>>') for 1st argument
 1000 |   _LIBCPP_HIDE_FROM_ABI map& operator=(initializer_list<value_type> __il) {
      |                              ^         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

it->destination_file_paths_per_part = std::move(*destination_file_paths_per_part);
auto destination_file_paths_per_part = readDestinationFilePathsPerPart(
zk, export_path, key, log);
it->destination_file_paths_per_part = std::move(destination_file_paths_per_part);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think there's something broken here? Does destination_file_paths_per_part need to be dereferenced?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

antalya antalya-26.3 port-antalya PRs to be ported to all new Antalya releases roadmap Key features and improvements for Antalya project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants