Zackriya-Solutions/meetily · error · Error
Meeting metadata not found
Error message
Meeting metadata not found
What it means
recoverMeeting first loads meeting metadata from IndexedDB via indexedDBService.getMeetingMetadata(meetingId) and throws when it resolves to nothing. IndexedDB in the WebView is the crash-recovery store, so this means no metadata record exists for that ID: it was never written, was removed by storage eviction or a user clearing app data, or the store/schema name changed after an upgrade. Everything downstream in recovery (transcripts, folderPath, audio) depends on metadata, so the flow aborts immediately.
Source
Thrown at frontend/src/hooks/useTranscriptRecovery.ts:116
// Sort by sequence ID
transcripts.sort((a, b) => (a.sequenceId || 0) - (b.sequenceId || 0));
return transcripts;
} catch (error) {
console.error('Failed to load meeting transcripts:', error);
return [];
}
}, []);
/**
* Recover a meeting from IndexedDB
*/
const recoverMeeting = useCallback(async (meetingId: string): Promise<{ success: boolean; audioRecoveryStatus?: AudioRecoveryStatus | null; meetingId?: string }> => {
setIsRecovering(true);
try {
// 1. Load meeting metadata
const metadata = await indexedDBService.getMeetingMetadata(meetingId);
if (!metadata) {
throw new Error('Meeting metadata not found');
}
// 2. Load all transcripts
const transcripts = await loadMeetingTranscripts(meetingId);
if (transcripts.length === 0) {
throw new Error('No transcripts found for this meeting');
}
// 3. Check for folder path
let folderPath = metadata.folderPath;
if (!folderPath) {
// Try to get from backend (might exist if only app crashed, not system)
try {
folderPath = await invoke<string>('get_meeting_folder_path');
} catch (error) {
folderPath = undefined;View on GitHub (pinned to 0281737d87)
Solutions
- Verify the meetingId still exists: enumerate the metadata store and only offer recovery for IDs it returns.
- Check whether WebView site data was cleared or evicted — if so, IndexedDB recovery is impossible; fall back to the on-disk audio folder (folderPath from the meetings list).
- If the IndexedDB schema version changed, verify the store name/keyPath in indexedDBService matches what the records were written under, and add migrations.
- Wrap recoverMeeting in try-catch and degrade to audio-only recovery rather than failing the whole recovery dialog.
Example fix
// before
const metadata = await indexedDBService.getMeetingMetadata(meetingId);
if (!metadata) {
throw new Error('Meeting metadata not found');
}
// after
const metadata = await indexedDBService.getMeetingMetadata(meetingId);
if (!metadata) {
toast.error('Meeting no longer in local storage', {
description: 'It may have been cleared. Recover from the saved audio file instead.',
});
return { success: false };
} Defensive patterns
Strategy: validation
Validate before calling
const recoverableIds = new Set(
(await indexedDBService.getAllMeetingMetadata()).map(m => m.meetingId)
);
if (!recoverableIds.has(meetingId)) {
toast.error('This meeting is no longer in local storage.');
return;
} Type guard
function isMeetingMetadata(m: unknown): m is MeetingMetadata {
const c = m as MeetingMetadata;
return !!c && typeof c.meetingId === 'string' && !!c.createdAt;
} Try / catch
try {
await recoverMeeting(meetingId);
} catch (e) {
if (e instanceof Error && e.message === 'Meeting metadata not found') {
// offer disk-based audio recovery from the meetings list instead of failing the dialog
}
} Prevention
- Persist meeting metadata to IndexedDB at recording start, not stop, so crashes always leave a record.
- Treat on-disk audio folders as the source of truth; IndexedDB is only an accelerator.
- Version the IndexedDB schema and migrate stores on upgrade so old IDs keep resolving.
When it happens
Trigger: recoverMeeting called with an ID that is not in the metadata object store: recovery list UI holds an ID from a previous session, WebView storage was evicted under disk pressure, IndexedDB schema version bumped and old stores were orphaned, or the crash happened before metadata was ever persisted.
Common situations: User cleared browsing/site data for the WebView, disk-pressure eviction on the IndexedDB volume, an app upgrade that recreated the DB without migrating records, or recovery offered for a meeting recorded before the persistence feature existed.
Related errors
AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16).
Data as JSON: /api/errors/95f1669c3a402486.
Report an issue: GitHub.