{"record":{"id":"edf31ea520360ab5","repo":"spacedriveapp/spacedrive","slug":"no-library-selected-use-client-switchtolibrary-edf31e","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/useQuery.ts","lineNumber":76,"sourceCode":" * }\n * ```\n */\nexport function useLibraryQuery<T extends LibraryQuery[\"type\"]>(\n\tquery: { type: T; input: Extract<LibraryQuery, { type: T }>[\"input\"] },\n\toptions?: Omit<\n\t\tUseQueryOptions<Extract<LibraryQuery, { type: T }>[\"output\"]>,\n\t\t\"queryKey\" | \"queryFn\"\n\t>\n): UseQueryResult<Extract<LibraryQuery, { type: T }>[\"output\"]> {\n\tconst client = useSpacedriveClient();\n\tconst wireMethod = WIRE_METHODS.libraryQueries[query.type];  // ← Auto-generated!\n\tconst libraryId = client.getCurrentLibraryId();\n\n\treturn useQuery({\n\t\tqueryKey: [query.type, libraryId, query.input],\n\t\tqueryFn: () => {\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, query.input);\n\t\t},\n\t\tenabled: !!libraryId && (options?.enabled ?? true),\n\t\t...options,\n\t}) as UseQueryResult<Extract<LibraryQuery, { type: T }>[\"output\"]>;\n}\n","sourceCodeStart":58,"sourceCodeEnd":87,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/packages/ts-client/src/hooks/useQuery.ts#L58-L87","documentation":"Returned by the ConduitService::get_entry helper when entry::Entity::find_by_id(entry_id) returns no row. It is a thin lookup used by sync and generation code to resolve entry ids stored on conduits and sync generations into full entry models.","triggerScenarios":"Calling get_entry with an id that has been deleted — most commonly a conduit whose source_entry_id or target_entry_id points at an entry removed by a reindex, or a historical sync_generation referencing a pruned entry.","commonSituations":"User deletes a synced folder on disk; the next indexer walk removes the entry rows; the conduit becomes dangling and any code resolving its entries hits this error.","solutions":["Identify the dangling reference: SELECT source_entry_id, target_entry_id FROM sync_conduit; and check both ids exist in entry.","Delete or recreate conduits whose endpoints no longer exist (delete_conduit).","Run a reindex of the source/target locations if the directories still exist on disk so fresh entry rows are created."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before resolving a conduit's endpoints, verify both still exist.\nasync fn conduit_endpoints_exist(db: &DatabaseConnection, c: &sync_conduit::Model) -> Result<bool> {\n    let n = entry::Entity::find()\n        .filter(entry::Column::Id.is_in([c.source_entry_id, c.target_entry_id]))\n        .all(db)\n        .await?\n        .len();\n    Ok(n == 2)\n}","typeGuard":null,"tryCatchPattern":"match svc.get_entry(entry_id).await {\n    Ok(e) => Ok(e),\n    Err(e) if e.to_string() == \"Entry not found\" => {\n        tracing::warn!(entry_id, \"dangling entry reference; conduit needs repair\");\n        Err(e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Cascade-delete or validate conduits when their endpoint entries are removed by reindex.","Periodically audit sync_conduit rows for dangling source/target ids.","Re-index locations after mount/unmount so entry rows track reality."],"tags":["rust","database","file-sync","not-found","dangling-reference"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}