{"record":{"id":"17eaec08d0b586ec","repo":"tonhowtf/omniget","slug":"omnidisc-device-preference-not-saved","errorCode":null,"errorMessage":"[omnidisc] device preference not saved","messagePattern":"\\[omnidisc\\] device preference not saved","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/lib/stores/omnidisc-voice-store.svelte.ts","lineNumber":658,"sourceCode":"    devices = await invoke<AudioDevices>(\"omnidisc_voice_devices\");\n  } catch (e) {\n    console.warn(\"[omnidisc] device list failed\", errorText(e));\n  } finally {\n    devicesLoading = false;\n  }\n}\n\nexport async function setDevice(kind: DeviceKind, id: string | null): Promise<string | null> {\n  const key = kind === \"input\" ? \"input_device\" : \"output_device\";\n  try {\n    await invoke(\"omnidisc_voice_set_device\", { kind, id });\n  } catch (e) {\n    return errorText(e);\n  }\n  try {\n    await updateSettings({ omnidisc: { voice: { [key]: id } } });\n  } catch (e) {\n    console.warn(\"[omnidisc] device preference not saved\", errorText(e));\n  }\n  return null;\n}\n\nexport async function setNoiseSuppression(enabled: boolean): Promise<void> {\n  try {\n    await invoke(\"omnidisc_voice_set_noise_suppression\", { enabled });\n  } catch (e) {\n    console.warn(\"[omnidisc] noise suppression failed\", errorText(e));\n  }\n  await updateSettings({ omnidisc: { voice: { noise_suppression: enabled } } });\n}\n\nexport async function setPttKey(key: string): Promise<void> {\n  await updateSettings({ omnidisc: { voice: { ptt_key: key } } });\n  await refreshPttStatus();\n  try {\n    await invoke(\"omnidisc_voice_ptt\", { pressed: false });","sourceCodeStart":640,"sourceCodeEnd":676,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src/lib/stores/omnidisc-voice-store.svelte.ts#L640-L676","documentation":"Logged in setDevice() when the backend call succeeded (device switched) but persisting the preference via updateSettings({ omnidisc: { voice: { [key]: id } } }) failed. The device change is active for this session only; it will not survive restart. Non-fatal warning; null is still returned so the caller treats the switch as successful.","triggerScenarios":"Calling setDevice(kind, id) when updateSettings throws: settings file unwritable, settings store/backend error, disk full, or serialization failure.","commonSituations":"Read-only config directory or restrictive file permissions; corrupted settings JSON on disk; settings backend temporarily unavailable; disk quota exceeded.","solutions":["Check errorText(e) to see whether the settings write failed due to permissions or parsing.","Verify the settings/config file location is writable by the app user.","Fix or delete a corrupted settings file so the store can rewrite it.","Queue a retry of updateSettings and re-attempt persistence on next app start.","Surface a 'preference not saved' toast so users know the change is session-only."],"exampleFix":"// before\ntry {\n  await updateSettings({ omnidisc: { voice: { [key]: id } } });\n} catch (e) {\n  console.warn(\"[omnidisc] device preference not saved\", errorText(e));\n}\n// after\ntry {\n  await updateSettings({ omnidisc: { voice: { [key]: id } } });\n} catch (e) {\n  console.warn(\"[omnidisc] device preference not saved\", errorText(e));\n  toast(\"Device changed, but the preference could not be saved.\");\n  scheduleSettingsRetry({ omnidisc: { voice: { [key]: id } } });\n}","handlingStrategy":"try-catch","validationCode":"// ensure settings store is writable before switching devices\nconst writable = await settingsStore.canWrite();\nif (!writable) toast(\"Settings are read-only; change will not persist.\");","typeGuard":"function isWriteError(e: unknown): e is { code: string } {\n  return typeof e === \"object\" && e !== null && \"code\" in e &&\n    String((e as { code: unknown }).code).match(/(permission|readonly|access)/i) !== null;\n}","tryCatchPattern":"try {\n  await updateSettings({ omnidisc: { voice: { [key]: id } } });\n} catch (e) {\n  console.warn(\"[omnidisc] device preference not saved\", errorText(e));\n  scheduleSettingsRetry({ omnidisc: { voice: { [key]: id } } });\n}","preventionTips":["Check config directory permissions at app startup.","Retry settings writes with backoff instead of dropping them.","Inform users when a change is session-only.","Validate/repair corrupted settings files on load."],"tags":["tauri","settings","persistence"],"backgroundTag":"file-write-failed","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}