Skip to content

fix(cli): parse Windows snapshot mappings#9723

Merged
timvisee merged 3 commits into
qdrant:devfrom
VectorPeak:codex/windows-snapshot-mapping
Jul 8, 2026
Merged

fix(cli): parse Windows snapshot mappings#9723
timvisee merged 3 commits into
qdrant:devfrom
VectorPeak:codex/windows-snapshot-mapping

Conversation

@VectorPeak

@VectorPeak VectorPeak commented Jul 7, 2026

Copy link
Copy Markdown

Windows probably is not where most people deploy Qdrant, so I see this as a small edge case rather than an urgent production issue. I opened the PR because the CLI already accepts PATH:NAME, and valid Windows drive-letter paths currently do not fit that parser. I think either accepting or declining this PR would be reasonable, or it can at least serve as an issue to discuss this edge case.

All Submissions:

⚠️ PRs must target the dev branch. If your PR targets master, please change the base branch to dev before requesting a review.

  • My PR targets the dev branch (not master) and my branch was created from dev.
  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?

Changes to Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

What changed

What Problem This Solves

CLI snapshot recovery accepts mappings in the documented <snapshot_file_path>:<target_collection_name> shape. That convention is straightforward for POSIX paths such as /tmp/collection.snapshot:test_collection and for relative paths such as collection.snapshot:test_collection, because the only colon is the separator between the snapshot path and the target collection name.

Windows absolute paths are different. A valid Windows path can contain a drive-letter prefix, so a normal mapping can look like this:

C:\tmp\collection.snapshot:test_collection

In that string, the first colon belongs to the path itself (C:), while the final colon is the actual mapping separator before test_collection.

Before this change, recover_snapshots() used split(':'), which treats every colon as a separator. For the Windows example above, the parser did not see one path and one collection name. It saw three pieces instead:

C
\tmp\collection.snapshot
test_collection

That means C was incorrectly treated as the snapshot path, \tmp\collection.snapshot was incorrectly treated as the collection name, and test_collection became an unexpected third part. Because of that third part, the parser rejected the mapping with Too many parts in snapshot mapping before snapshot recovery could start.

So the issue is not that the Windows path is invalid. The path is valid, but the CLI mapping parser consumes the drive-letter colon as if it were part of the PATH:NAME protocol. This makes a valid Windows snapshot path impossible to express through the documented CLI mapping format.

Changes

This PR moves snapshot mapping parsing into a small internal SnapshotMapping type and parses CLI mappings from the final colon. Earlier colons stay with the snapshot path, so Windows drive-letter paths keep their drive prefix while the documented PATH:NAME shape remains unchanged.

It also avoids the same string-protocol round trip in full-storage snapshot recovery. recover_full_snapshot() already reads structured snapshot configuration, so it now builds SnapshotMapping values directly instead of formatting unpacked snapshot paths back into PATH:NAME strings and parsing them again.

Evidence

The focused tests cover the old failing shape and the nearby parser boundaries:

C:\tmp\collection.snapshot:test_collection

Before this change, that mapping could be split into C, \tmp\collection.snapshot, and test_collection, which hit Too many parts in snapshot mapping. After this change, the parser returns:

snapshot path: C:\tmp\collection.snapshot
collection:    test_collection

The test suite also covers POSIX absolute paths, relative paths, paths with earlier colons, missing separators, empty paths, and empty collection names.

Possible call chain / impact

qdrant --snapshot <PATH:NAME>
  -> recover_collections_from_snapshot_args(...)
  -> recover_snapshots(...)
  -> SnapshotMapping::from_cli_arg(...)
  -> Collection::restore_snapshot(...)
qdrant --storage-snapshot <PATH>
  -> recover_full_snapshot(...)
  -> SnapshotConfig.collections_mapping
  -> SnapshotMapping { snapshot_path, collection_name }
  -> recover_snapshot_mappings(...)

This only changes startup CLI snapshot mapping parsing and the internal full-storage snapshot mapping handoff. It does not change CLI flag names, collection restore behavior after parsing, REST/gRPC snapshot recovery APIs, or snapshot storage formats.

Scope

Affected:

  • --snapshot PATH:NAME
  • --collection-snapshot PATH:NAME
  • internal full-storage snapshot recovery mapping construction

Unchanged:

  • CLI flag names and documented PATH:NAME shape
  • collection restore behavior after a mapping has been parsed
  • REST and gRPC snapshot recovery APIs
  • snapshot storage formats

Validation

  • cargo +nightly fmt --all --check
  • git diff --check
  • cargo test -p qdrant snapshot_mapping -- --nocapture

Focused test result:

running 8 tests
test snapshots::tests::snapshot_mapping_accepts_relative_path ... ok
test snapshots::tests::snapshot_mapping_accepts_windows_absolute_path ... ok
test snapshots::tests::snapshot_mapping_accepts_posix_absolute_path ... ok
test snapshots::tests::snapshot_mapping_rejects_empty_collection_name - should panic ... ok
test snapshots::tests::snapshot_mapping_rejects_missing_separator - should panic ... ok
test snapshots::tests::snapshot_mapping_rejects_windows_path_without_collection_name - should panic ... ok
test snapshots::tests::snapshot_mapping_rejects_empty_path - should panic ... ok
test snapshots::tests::snapshot_mapping_splits_on_last_colon ... ok

test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 147 filtered out; finished in 0.00s

AI disclosure

Commit 97dd739c497f200e8be92d198dca9ffa18a7055e was prepared with AI assistance. Initial prompt intent: fix Qdrant CLI snapshot mapping parsing so Windows drive-letter paths are not split at the drive colon.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@src/snapshots.rs`:
- Around line 22-40: The parsing in from_cli_arg currently treats the last colon
as the separator, so a Windows drive-letter colon can be mistaken for the
snapshot/name boundary. Update from_cli_arg in src/snapshots.rs to explicitly
validate the split result by rejecting path-like collection_name values (for
example, ones containing path separators or otherwise looking like a filesystem
path), so malformed inputs without a real ":collection_name" suffix still
trigger the intended missing-collection panic instead of producing a bogus
path/name pair.
🪄 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: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 71e0e4b0-fd9f-48ec-835a-8cb5af1c01fd

📥 Commits

Reviewing files that changed from the base of the PR and between bcfffc5 and 97dd739.

📒 Files selected for processing (1)
  • src/snapshots.rs

Comment thread src/snapshots.rs
@qdrant qdrant deleted a comment from coderabbitai Bot Jul 8, 2026
VectorPeak and others added 3 commits July 8, 2026 13:34
Parse CLI snapshot mappings from the final colon so Windows drive-letter paths keep their drive prefix. Keep full-snapshot recovery on typed mappings instead of formatting paths back into the CLI string protocol.

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Reject path-like collection names when parsing CLI snapshot mappings so a Windows path without a target collection suffix reports the intended missing-collection error instead of producing a bogus mapping.

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@timvisee
timvisee force-pushed the codex/windows-snapshot-mapping branch from d382e7e to a561491 Compare July 8, 2026 11:41
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 6784622b-d953-4f61-a3bf-b94a94a8e7f0

📥 Commits

Reviewing files that changed from the base of the PR and between d382e7e and a561491.

📒 Files selected for processing (1)
  • src/snapshots.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/snapshots.rs

📝 Walkthrough

Walkthrough

This change introduces a SnapshotMapping struct with a from_cli_arg constructor that parses "path:collection" strings by splitting on the last colon, validating non-empty path/collection fields and rejecting slashes or backslashes in collection names. recover_snapshots and recover_full_snapshot are refactored to build SnapshotMapping instances and route through a new recover_snapshot_mappings function, replacing prior string-splitting logic. Unit tests cover various path formats and panic conditions.

Estimated code review effort: 2 (Simple) | ~12 minutes

Poem

A colon split, the last one found,
No more parsing round and round.
Paths and names now neatly paired,
Panics catch what's ill-prepared.
This rabbit hops with tidy code, 🐇✂️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: fixing CLI parsing for Windows snapshot mappings.
Description check ✅ Passed The description accurately explains the snapshot mapping parser fix and related tests.
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.

@timvisee timvisee left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, this makes sense. I agree that splitting at the last : is a good idea.

I've merged some tests on your branch and rebased on the latest dev to make tests pass.

@timvisee
timvisee merged commit a7eb459 into qdrant:dev Jul 8, 2026
16 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