spacedriveapp/spacedrive · error
No library selected. Use client.switchToLibrary() first.
Error message
No library selected. Use client.switchToLibrary() first.
What it means
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.
Source
Thrown at packages/ts-client/src/hooks/useQuery.ts:76
* }
* ```
*/
export function useLibraryQuery<T extends LibraryQuery["type"]>(
query: { type: T; input: Extract<LibraryQuery, { type: T }>["input"] },
options?: Omit<
UseQueryOptions<Extract<LibraryQuery, { type: T }>["output"]>,
"queryKey" | "queryFn"
>
): UseQueryResult<Extract<LibraryQuery, { type: T }>["output"]> {
const client = useSpacedriveClient();
const wireMethod = WIRE_METHODS.libraryQueries[query.type]; // ← Auto-generated!
const libraryId = client.getCurrentLibraryId();
return useQuery({
queryKey: [query.type, libraryId, query.input],
queryFn: () => {
if (!libraryId) {
throw new Error("No library selected. Use client.switchToLibrary() first.");
}
// Client.execute() automatically adds library_id to the request
// as a sibling field (not inside payload)
return client.execute(wireMethod, query.input);
},
enabled: !!libraryId && (options?.enabled ?? true),
...options,
}) as UseQueryResult<Extract<LibraryQuery, { type: T }>["output"]>;
}
View on GitHub (pinned to 6dfeccf211)
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.
Defensive patterns
Strategy: validation
Validate before calling
// Before resolving a conduit's endpoints, verify both still exist.
async fn conduit_endpoints_exist(db: &DatabaseConnection, c: &sync_conduit::Model) -> Result<bool> {
let n = entry::Entity::find()
.filter(entry::Column::Id.is_in([c.source_entry_id, c.target_entry_id]))
.all(db)
.await?
.len();
Ok(n == 2)
} Try / catch
match svc.get_entry(entry_id).await {
Ok(e) => Ok(e),
Err(e) if e.to_string() == "Entry not found" => {
tracing::warn!(entry_id, "dangling entry reference; conduit needs repair");
Err(e)
}
Err(e) => Err(e),
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unexpected response: ${JSON.stringify(response)}
- No library selected. Use client.switchToLibrary() first.
- Library '{}' not found
- No library selected. Use 'sd library switch' to select a lib
- Library with ID '${libraryId}' not found
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/edf31ea520360ab5.
Report an issue: GitHub.