{"record":{"id":"898360f28d91f375","repo":"spacedriveapp/spacedrive","slug":"no-library-selected-use-sd-library-switch-to-se-898360","errorCode":null,"errorMessage":"No library selected. Use 'sd library switch' to select a library first.","messagePattern":"No library selected\\. Use 'sd library switch' to select a library first\\.","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"apps/cli/src/domains/sync/mod.rs","lineNumber":69,"sourceCode":"\t\t\tif args.watch {\n\t\t\t\trun_watch_mode(ctx, since, peer_id, &args).await?;\n\t\t\t} else {\n\t\t\t\trun_single_query(ctx, since, peer_id, &args).await?;\n\t\t\t}\n\t\t}\n\t}\n\tOk(())\n}\n\nasync fn run_single_query(\n\tctx: &Context,\n\tsince: Option<DateTime<Utc>>,\n\tpeer_id: Option<uuid::Uuid>,\n\targs: &SyncMetricsArgs,\n) -> Result<()> {\n\t// Check if we have a library ID\n\tlet library_id = ctx.library_id.ok_or_else(|| {\n\t\tanyhow::anyhow!(\"No library selected. Use 'sd library switch' to select a library first.\")\n\t})?;\n\n\t// Call the sync metrics API\n\tlet input = GetSyncMetricsInput {\n\t\tsince,\n\t\tpeer_id,\n\t\tmodel_type: args.model.clone(),\n\t\tstate_only: if args.state { Some(true) } else { None },\n\t\toperations_only: if args.operations { Some(true) } else { None },\n\t\terrors_only: if args.errors { Some(true) } else { None },\n\t};\n\n\tlet json_response = ctx.core.query(&input, Some(library_id)).await?;\n\tlet output: sd_core::ops::sync::get_metrics::GetSyncMetricsOutput =\n\t\tserde_json::from_value(json_response)?;\n\n\tif args.json {\n\t\tprintln!(\"{}\", serde_json::to_string_pretty(&output.metrics)?);","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/apps/cli/src/domains/sync/mod.rs#L51-L87","documentation":"Thrown by 'sd sync metrics' (single-query mode) when ctx.library_id is None. Sync metrics (GetSyncMetricsInput) are queried per-library, and the CLI Context had no current library in its config, so the command refuses before calling the daemon. The message directs you to 'sd library switch'.","triggerScenarios":"Running 'sd sync metrics' (with any --since/--peer/model filters) on a CLI that has no current_library_id in its config.","commonSituations":"First use on a new machine; library was deleted leaving the config pointing nowhere (context startup clears it); automated scripts that never switch libraries.","solutions":["Run 'sd library switch <library-id>' (find IDs via 'sd library list')","Create a library if the daemon has none: 'sd library create'","Re-run 'sd sync metrics'"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let Some(library_id) = ctx.get_current_library_id() else {\n    eprintln!(\"No current library. Run 'sd library list', then 'sd library switch <id>'.\");\n    return Ok(());\n};","typeGuard":"fn has_current_library(ctx: &Context) -> bool {\n    ctx.library_id.is_some()\n}","tryCatchPattern":null,"preventionTips":["Run 'sd library switch' at the start of any session using sync metrics","Check 'sd config get current_library_id' when in doubt","Handle a None library id once in a shared helper rather than per command"],"tags":["cli","sync","metrics","library","config"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}