spacedriveapp/spacedrive · error · anyhow::Error
No paired devices found. Pair a device first with: sd networ
Error message
No paired devices found. Pair a device first with: sd network pair generate # on this device sd network pair join <code> # on the other device
What it means
Thrown by the interactive 'sd library sync' wizard (step 2) after it queries the daemon with ListPairedDevicesInput { connected_only: false } and receives an empty devices list. It aborts the wizard before any device selection because library sync requires a peer device. The message itself tells you the pairing commands to run.
Source
Thrown at apps/cli/src/domains/library/mod.rs:307
let library_idx = select("Select local library to sync", &library_choices)?;
let local_library_id = libraries[library_idx].id;
println!(
"\n✓ Selected local library: {}\n",
libraries[library_idx].name
);
// Step 2: Select remote device from paired devices
let paired_devices: ListPairedDevicesOutput = execute_core_query!(
ctx,
ListPairedDevicesInput {
connected_only: false
}
);
if paired_devices.devices.is_empty() {
anyhow::bail!(
"No paired devices found.\n\
Pair a device first with:\n\
sd network pair generate # on this device\n\
sd network pair join <code> # on the other device"
);
}
let device_choices: Vec<String> = paired_devices
.devices
.iter()
.map(|d| {
let status = if d.is_connected {
"connected"
} else {
"paired"
};
format!("{} - {} ({})", d.name, d.os_version, status)
})View on GitHub (pinned to 6dfeccf211)
Solutions
- Run 'sd network pair generate' on this device to create a pairing code
- On the other device run 'sd network pair join <code>' with that code
- Confirm the pairing took effect by listing paired devices before retrying 'sd library sync'
- If pairing was done previously, verify the daemon is running against the expected data directory (pairing records are stored there)
Example fix
// before: wizard discovers empty pairing list and bails mid-flow
if paired_devices.devices.is_empty() {
anyhow::bail!("No paired devices found. ...");
}
// after: check pairing up-front so the user is told before answering prompts
let paired_devices: ListPairedDevicesOutput = execute_core_query!(
ctx,
ListPairedDevicesInput { connected_only: false }
);
if paired_devices.devices.is_empty() {
println!("No paired devices found. Pair one first:");
println!(" sd network pair generate");
return Ok(()); // graceful exit instead of hard bail
} Defensive patterns
Strategy: validation
Validate before calling
// Before launching the wizard, ask the daemon for paired devices
let paired: ListPairedDevicesOutput = execute_core_query!(
ctx,
ListPairedDevicesInput { connected_only: false }
);
if paired.devices.is_empty() {
eprintln!("Pair a device first: sd network pair generate / sd network pair join <code>");
return Ok(());
} Type guard
fn has_paired_devices(out: &ListPairedDevicesOutput) -> bool {
!out.devices.is_empty()
} Try / catch
match run_sync_wizard(ctx).await {
Err(e) if e.to_string().contains("No paired devices") => {
eprintln!("Skipping sync: {}", e);
Ok(())
}
other => other,
} Prevention
- Pair devices immediately after install so the wizard never starts from an empty list
- In automation, pre-flight the paired-device query before entering interactive prompts
- Remember pairing state lives in the daemon's data directory - changing it invalidates pairings
When it happens
Trigger: Running 'sd library sync' (interactive setup) on a device whose daemon has zero entries in its pairing database. The query is execute_core_query!(ctx, ListPairedDevicesInput { connected_only: false }), so even offline paired devices count; empty means nothing was ever paired.
Common situations: Fresh install before any pairing was done; the daemon data directory was reset or changed (pairings live in daemon state, not in the CLI); testing the wizard against a dev daemon with a clean state.
Related errors
- Remote device {} is not online
- No libraries found on remote device. Use 'Share my library'
- Operation aborted by user
- Library merging is not yet implemented
- Path does not exist: {}
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/b75e83d29d217cc0.
Report an issue: GitHub.