tonhowtf/omniget · warning
reopen failed
Error message
reopen failed
What it means
notebooksStore.reopen() reopens a closed notebook via notesNotebooksReopen (Tauri command 'study:notes:notebooks:reopen') then refresh(). On rejection the catch logs 'reopen failed' and the notebook stays in the closed list with no user-visible error.
Solutions
- Read the logged rejection reason from notesNotebooksReopen.
- Verify the notebook is actually closed (check this.list) before calling reopen; skip the call if already open.
- Confirm 'study:notes:notebooks:reopen' exists and is permitted in capabilities.
- Handle 'already open' / 'not found' backend errors as non-fatal and just refresh().
- Retry once on transient IPC failures and surface a toast if it still fails.
Example fix
// before
await notesNotebooksReopen(notebookId);
// after
const nb = this.list.find((n) => n.id === notebookId);
if (nb && nb.closed) {
await notesNotebooksReopen(notebookId);
}
await this.refresh(); Defensive patterns
Strategy: validation
Validate before calling
const nb = notebooksStore.list.find((n) => n.id === notebookId);
if (!nb) { showToast('Notebook no longer exists'); return; }
if (!nb.closed) return; // already open, nothing to do Type guard
function isReopenable(nb: Notebook | undefined): nb is Notebook {
return !!nb && nb.closed === true;
} Try / catch
try {
await notebooksStore.reopen(notebookId);
} catch (e) {
console.warn('reopen rejected:', e);
await notebooksStore.refresh(); // re-sync real closed/open state
showToast('Reopen failed — state refreshed');
} Prevention
- Only call reopen for notebooks currently marked closed
- Treat 'already open' or 'not found' backend errors as benign and refresh
- Refresh after failure so the closed-list stays accurate
- Handle double-click/debounce on reopen buttons
- Verify the reopen command exists in the deployed backend version
When it happens
Trigger: notesNotebooksReopen(notebookId) rejects: the notebook is not in a closed state (backend state validation), the notebook was deleted, DB write failure, plugin/capability misconfiguration, or IPC failure.
Common situations: Reopening a notebook that was hard-deleted in another session; double-click producing a second reopen of an already-open notebook; backend rejects because reopen is only valid for closed entities; DB locked; command not present in the installed backend version.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- notebooksStore.hydrate failed
- notebooksStore.refresh failed
- create notebook failed
- rename failed
- close failed
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/22c8dc4d158c6b5e.
Report an issue: GitHub.
Appendix: source
Thrown at src/lib/study-notes/notebooks-store.svelte.ts:141
async close(notebookId: number) {
try {
await notesNotebooksClose(notebookId);
if (this.activeId === notebookId) {
await this.setActive(1);
}
await this.refresh();
} catch (e) {
console.warn("close failed", e);
}
}
async reopen(notebookId: number) {
try {
await notesNotebooksReopen(notebookId);
await this.refresh();
} catch (e) {
console.warn("reopen failed", e);
}
}
async delete(notebookId: number, force = false): Promise<NotebookDeleteReport> {
try {
const r = await notesNotebooksDelete({ notebookId, force });
if (r.deleted && this.activeId === notebookId) {
await this.setActive(1);
}
await this.refresh();
return r;
} catch (e) {
console.warn("delete failed", e);
return { deleted: false, page_count: 0 };
}
}
async movePage(args: {View on GitHub (pinned to 8600b91f42)