{"record":{"id":"be344c28bb872db0","repo":"spacedriveapp/spacedrive","slug":"failed-to-parse-cloud-path","errorCode":null,"errorMessage":"Failed to parse cloud path: {}","messagePattern":"Failed to parse cloud path: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"apps/cli/src/domains/location/mod.rs","lineNumber":222,"sourceCode":"\n\t\t// Get cloud path within the volume\n\t\tlet cloud_path = text(\n\t\t\t\"Enter path within volume (e.g., / for root or /photos)\",\n\t\t\tfalse,\n\t\t)?\n\t\t.unwrap();\n\n\t\t// Construct service-based URI: mount_point + path\n\t\tlet mount_point_str = mount_point.to_string_lossy();\n\t\tlet full_uri = if cloud_path.starts_with('/') {\n\t\t\tformat!(\"{}{}\", mount_point_str, cloud_path)\n\t\t} else {\n\t\t\tformat!(\"{}/{}\", mount_point_str, cloud_path)\n\t\t};\n\n\t\t// Parse the URI to create SdPath\n\t\tSdPath::from_uri(&full_uri)\n\t\t\t.map_err(|e| anyhow::anyhow!(\"Failed to parse cloud path: {}\", e))?\n\t};\n\n\t// 2. Name (optional)\n\tlet name = text(\"Location name\", true)?;\n\n\t// 3. Index mode\n\tlet mode_idx = select(\n\t\t\"Select indexing mode\",\n\t\t&[\n\t\t\t\"Content (recommended - indexes file metadata and content hashes)\".to_string(),\n\t\t\t\"Shallow (metadata only - faster)\".to_string(),\n\t\t\t\"Deep (full analysis - slowest)\".to_string(),\n\t\t],\n\t)?;\n\n\tlet mode = match mode_idx {\n\t\t0 => IndexMode::Content,\n\t\t1 => IndexMode::Shallow,","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/apps/cli/src/domains/location/mod.rs#L204-L240","documentation":"Wraps the SdPathParseError from SdPath::from_uri() when the interactive cloud-location flow concatenates the volume's mount point with the user-entered cloud path (mount_point_str + cloud_path) and parses the result. Because a scheme-separated URI is being built (e.g. s3://bucket/photos), failure means the scheme of the mount point is not recognized by CloudServiceType::from_scheme, or the combined string is malformed.","triggerScenarios":"A tracked volume whose mount point uses an unsupported or stale scheme string; a cloud path that itself contains '://' so splitn(2, \"://\") mis-splits the URI; an empty mount point making the joined string a bare local path that then mismatches expectations downstream.","commonSituations":"Volume registered under a cloud service that this build no longer supports; mount point edited to a custom scheme; pasting a full URI like s3://bucket/x as the 'path within volume' so the join produces s3://buckets3://bucket/x.","solutions":["Enter only the path within the volume (e.g. /photos), not a full URI, at the 'Enter path within volume' prompt","Check the volume's mount point with the volume list command; re-add it via 'sd volume add-cloud' if its scheme is unrecognized","Avoid '://' inside the cloud path segment","Ensure CLI and daemon builds match so both know the same cloud service schemes"],"exampleFix":"// before: pasting a full URI silently builds a corrupt URI\nlet cloud_path = text(\"Enter path within volume (e.g., / for root or /photos)\", false)?.unwrap();\n\n// after: reject full URIs at the prompt\nlet cloud_path = text(\"Enter path within volume (e.g., / for root or /photos)\", false)?.unwrap();\nanyhow::ensure!(!cloud_path.contains(\"://\"), \"Enter a path inside the volume, not a full URI\");","handlingStrategy":"validation","validationCode":"// Validate the joined URI before handing it to from_uri\nlet full_uri = format!(\"{}{}\", mount_point_str, cloud_path);\nanyhow::ensure!(\n    full_uri.matches(\"://\").count() == 1,\n    \"cloud path must be a path inside the volume, not a full URI\"\n);\nanyhow::ensure!(\n    sd_core::volume::backend::CloudServiceType::from_scheme(\n        full_uri.split_once(\":://\").unwrap().0\n    ).is_some(),\n    \"mount point scheme is not a supported cloud service\"\n);\nlet sd_path = SdPath::from_uri(&full_uri)?;","typeGuard":"fn cloud_uri_is_parseable(mount_point: &std::path::Path, cloud_path: &str) -> bool {\n    let uri = format!(\"{}{}\", mount_point.to_string_lossy(), cloud_path);\n    uri.matches(\"://\").count() == 1 && SdPath::from_uri(&uri).is_ok()\n}","tryCatchPattern":"match SdPath::from_uri(&full_uri) {\n    Ok(p) => p,\n    Err(SdPathParseError::UnknownScheme) => anyhow::bail!(\n        \"volume '{}' has unsupported mount point '{}'; re-add it with sd volume add-cloud\",\n        selected_volume.name, mount_point_str\n    ),\n    Err(e) => return Err(anyhow::anyhow!(\"Failed to parse cloud path: {}\", e)),\n}","preventionTips":["Enter only the in-volume path (/photos), never a full s3:// URI, at the prompt","Keep volume mount points in service-URI form (s3://bucket)","Match CLI and daemon builds so both recognize the same cloud schemes"],"tags":["cli","location","cloud","uri-parsing","volumes"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}