spacedriveapp/spacedrive · error · anyhow::Error

No cloud volumes with mount points found. Cloud volumes must

Error message

No cloud volumes with mount points found. Cloud volumes must have mount points.

What it means

Defensive guard after building the cloud-volume choice list in the interactive location-add flow. In the current code every tracked volume is unconditionally formatted into volume_choices (there is no filter), so given the earlier empty-volumes bail at line 173 this branch is effectively unreachable; it exists to catch volumes that lack a usable mount_point, which the SdPath URI construction below depends on.

Source

Thrown at apps/cli/src/domains/location/mod.rs:194

			);
		}

		// Present volume choices (showing service-based URIs)
		let volume_choices: Vec<String> = volumes
			.volumes
			.iter()
			.map(|v| {
				format!(
					"{} ({}) - {}",
					v.name,
					v.mount_point.display(), // Show mount point like "s3://bucket"
					v.volume_type
				)
			})
			.collect();

		if volume_choices.is_empty() {
			anyhow::bail!(
				"No cloud volumes with mount points found. Cloud volumes must have mount points."
			);
		}

		let volume_idx = select("Select cloud volume", &volume_choices)?;

		// Get the mount point for the selected volume
		let selected_volume = &volumes.volumes[volume_idx];
		let mount_point = &selected_volume.mount_point;

		// Get cloud path within the volume
		let cloud_path = text(
			"Enter path within volume (e.g., / for root or /photos)",
			false,
		)?
		.unwrap();

		// Construct service-based URI: mount_point + path

View on GitHub (pinned to 6dfeccf211)

Solutions

  1. Re-run 'sd volume add-cloud' for the affected volume so it gets a proper service-style mount point
  2. Inspect the volume list output to see which volume has an empty or unexpected mount point
  3. If you maintain this code, filter volumes without scheme-based mount points explicitly so the guard is reachable and accurate

Example fix

// before: guard is unreachable because map() never filters
let volume_choices: Vec<String> = volumes.volumes.iter().map(|v| format!(...)).collect();

// after: make the intent real by filtering mount-point-less volumes
let volume_choices: Vec<String> = volumes
    .volumes
    .iter()
    .filter(|v| v.mount_point.to_string_lossy().contains("://"))
    .map(|v| format!("{} ({}) - {}", v.name, v.mount_point.display(), v.volume_type))
    .collect();
Defensive patterns

Strategy: validation

Validate before calling

let usable: Vec<_> = volumes
    .volumes
    .iter()
    .filter(|v| v.mount_point.to_string_lossy().contains("://"))
    .collect();
if usable.is_empty() {
    eprintln!("No cloud volumes with a service-style mount point; re-add with 'sd volume add-cloud'");
    return Ok(());
}

Type guard

fn volume_has_service_mount(v: &VolumeInfo) -> bool {
    v.mount_point.to_string_lossy().contains("://")
}

Prevention

When it happens

Trigger: Only if tracked volumes exist but produce zero selectable choices - with the current map() that cannot happen; historically this guarded volumes whose mount_point was empty or local-style rather than a service URI like s3://bucket.

Common situations: A volume registered with a missing/blank mount point after a partial 'sd volume add-cloud'; schema or version drift changing what mount_point contains.

Related errors


AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16). Data as JSON: /api/errors/6138c61c490dc6ad. Report an issue: GitHub.