{"record":{"id":"dcba0bdbe6d5bb8c","repo":"spacedriveapp/spacedrive","slug":"no-library-selected-use-client-switchtolibrary","errorCode":null,"errorMessage":"No library selected. Use client.switchToLibrary() first.","messagePattern":"No library selected\\. Use client\\.switchToLibrary\\(\\) first\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ts-client/src/hooks/useMutation.ts","lineNumber":91,"sourceCode":"\t\t\tExtract<LibraryAction, { type: T }>[\"output\"],\n\t\t\tError,\n\t\t\tExtract<LibraryAction, { type: T }>[\"input\"]\n\t\t>,\n\t\t\"mutationFn\"\n\t>\n): UseMutationResult<\n\tExtract<LibraryAction, { type: T }>[\"output\"],\n\tError,\n\tExtract<LibraryAction, { type: T }>[\"input\"]\n> {\n\tconst client = useSpacedriveClient();\n\tconst wireMethod = WIRE_METHODS.libraryActions[type];  // ← Auto-generated!\n\n\treturn useMutation({\n\t\tmutationFn: (input) => {\n\t\t\tconst libraryId = client.getCurrentLibraryId();\n\t\t\tif (!libraryId) {\n\t\t\t\tthrow new Error(\"No library selected. Use client.switchToLibrary() first.\");\n\t\t\t}\n\n\t\t\t// Client.execute() automatically adds library_id to the request\n\t\t\t// as a sibling field (not inside payload)\n\t\t\treturn client.execute(wireMethod, input);\n\t\t},\n\t\t...options,\n\t}) as UseMutationResult<\n\t\tExtract<LibraryAction, { type: T }>[\"output\"],\n\t\tError,\n\t\tExtract<LibraryAction, { type: T }>[\"input\"]\n\t>;\n}\n","sourceCodeStart":73,"sourceCodeEnd":105,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/packages/ts-client/src/hooks/useMutation.ts#L73-L105","documentation":"Returned by ConduitService::get_conduit_by_uuid(uuid) when no sync_conduit row matches the uuid filter. This is the UUID-keyed variant of the by-id lookup, used when clients address conduits by their public UUID (set via Uuid::new_v4() at creation) rather than the numeric id.","triggerScenarios":"Calling get_conduit_by_uuid with a UUID that is not in the sync_conduit table — malformed/truncated UUID string parsed into a Uuid, a conduit from another library, or a deleted conduit.","commonSituations":"UUID copied with a missing segment (still parses as nil/other value in some paths), stale references in client state after deletion, cross-library reference leaks.","solutions":["Verify the exact UUID: SELECT id, uuid FROM sync_conduit WHERE uuid = '<uuid>';.","Confirm the UUID round-trips unchanged from the client (no truncation, case/normalization is handled by Uuid parsing).","If the conduit was deleted, re-create it and update the stored reference."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the reference shape before hitting the DB.\nfn is_valid_conduit_uuid(s: &str) -> bool {\n    uuid::Uuid::parse_str(s).is_ok()\n}","typeGuard":"fn is_conduit_uuid(v: &serde_json::Value) -> bool {\n    v.as_str().map(uuid::Uuid::parse_str).map(|r| r.is_ok()).unwrap_or(false)\n}","tryCatchPattern":"match svc.get_conduit_by_uuid(uuid).await {\n    Ok(c) => Ok(c),\n    Err(e) if e.to_string() == \"Conduit not found\" => {\n        // stale external reference: log, clear cached uuid, prompt re-selection\n        clear_cached_conduit_uuid(uuid);\n        Err(e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Parse/validate UUID strings at the API boundary before converting to Uuid.","Store conduit UUIDs only from create_conduit's returned model, never hand-typed.","Clean up persisted UUID references when conduits are deleted."],"tags":["rust","database","file-sync","uuid","not-found"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}