{"record":{"id":"afea1d6026c161d8","repo":"spacedriveapp/spacedrive","slug":"destination-must-have-a-device-slug-for-cross-devi","errorCode":null,"errorMessage":"Destination must have a device slug for cross-device transfer","messagePattern":"Destination must have a device slug for cross-device transfer","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"core/src/ops/files/copy/strategy.rs","lineNumber":298,"sourceCode":"\t\t\t\t// Both remote - not supported yet (would require relay)\n\t\t\t\t// Default to Push for now\n\t\t\t\tdebug!(\"Both source and destination are remote - defaulting to Push\");\n\t\t\t\tTransferDirection::Push\n\t\t\t}\n\t\t}\n\t}\n\n\t/// Execute a PUSH operation (local -> remote)\n\tasync fn execute_push<'a>(\n\t\t&self,\n\t\tctx: &JobContext<'a>,\n\t\tsource: &SdPath,\n\t\tdestination: &SdPath,\n\t\t_verify_checksum: bool,\n\t\tprogress_callback: Option<&ProgressCallback<'a>>,\n\t) -> Result<u64> {\n\t\tlet dest_device_slug = destination.device_slug().ok_or_else(|| {\n\t\t\tanyhow::anyhow!(\"Destination must have a device slug for cross-device transfer\")\n\t\t})?;\n\n\t\tlet library = ctx.library();\n\t\tlet dest_device_id = library\n\t\t\t.resolve_device_slug(dest_device_slug)\n\t\t\t.ok_or_else(|| anyhow::anyhow!(\n\t\t\t\t\"Could not resolve destination device slug '{}' to UUID in library {}. Device may not be registered in this library.\",\n\t\t\t\tdest_device_slug,\n\t\t\t\tlibrary.id()\n\t\t\t))?;\n\n\t\tdebug!(\n\t\t\t\"RemoteTransferStrategy PUSH: {} -> device:{} ({})\",\n\t\t\tsource, dest_device_slug, dest_device_id\n\t\t);\n\n\t\tlet networking = ctx\n\t\t\t.networking_service()","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/ops/files/copy/strategy.rs#L280-L316","documentation":"Cross-device push (core/src/ops/files/copy/strategy.rs:298) requires the destination SdPath to carry a device slug, because it must resolve which peer device receives the file. SdPath::device_slug() returns Some only for the Physical variant (core/src/domain/addressing.rs:538); Cloud, Content, and Sidecar variants return None and hit this error before the transfer starts. Note the very next step resolves that slug to a device UUID via Library::resolve_device_slug, so the slug must also belong to a device registered in the current library.","triggerScenarios":"Invoking the cross-device copy strategy with a destination like Cloud {'s3://bucket/...'}, Content {'content://<uuid>'}, or a Sidecar path — none of which identify a target device.","commonSituations":"A copy router that treats 'not local' as 'cross-device' and passes cloud destinations to the push path; UI building destinations from display URIs of non-physical schemes; serialization drift where a Physical destination is decoded as Content.","solutions":["Route by SdPath variant: only Physical destinations with a peer slug go to execute_push; Cloud/Content destinations need their own cloud upload/content-ingest path.","Before dispatch, validate `matches!(destination, SdPath::Physical { .. }) && destination.device_slug().is_some()`.","If the target device was expected to be a peer but the slug is missing, rebuild the destination as Physical { device_slug: <peer slug>, path } from library device records."],"exampleFix":"// before\nCrossDeviceCopyStrategy.execute(ctx, source, cloud_destination, true, cb).await\n\n// after\nlet Some(slug) = destination.device_slug() else {\n    anyhow::bail!(\"destination {} has no device; route cloud targets to the cloud uploader\", destination.display());\n};\nCrossDeviceCopyStrategy.execute(ctx, source, destination, true, cb).await","handlingStrategy":"type-guard","validationCode":"// only Physical destinations with a slug may enter the push path\nif destination.device_slug().is_none() {\n    anyhow::bail!(\"cross-device push requires a Physical destination with a device slug, got {}\", destination.display());\n}","typeGuard":"fn is_push_destination(dest: &SdPath) -> bool {\n    matches!(dest, SdPath::Physical { .. }) && dest.device_slug().is_some()\n}","tryCatchPattern":"// route by destination kind instead of failing the transfer\nif !is_push_destination(destination) {\n    return CloudCopyStrategy::upload(ctx, source, destination).await;\n}\nCrossDeviceCopyStrategy.execute(ctx, source, destination, verify, cb).await","preventionTips":["Distinguish 'non-local Physical' (cross-device push) from 'Cloud/Content' (cloud writer) in the router — do not lump them together.","Verify the slug resolves via Library::resolve_device_slug before starting the push.","Build destinations for peers from library device records, never from display strings."],"tags":["files","copy","cross-device","sd-path","multi-device"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}