cjpais/Handy · warning
Failed to sync theme from settings:
Error message
Failed to sync theme from settings:
What it means
syncThemeFromSettings calls getAppSettings and applies result.data.theme ('light' | 'dark' | 'system') to the document. The ok-status path is handled and the error-status path is silently ignored; this catch only sees a rejected invoke (backend unreachable, command unregistered, store plugin not ready, browser context). The visible symptom is the app keeping the default/system appearance instead of the user's persisted choice.
Source
Thrown at src/lib/utils/theme.ts:61
export const getStoredTheme = (): Theme => {
try {
const stored = localStorage.getItem(THEME_STORAGE_KEY);
if (isTheme(stored)) return stored;
} catch {
// ignore
}
return "system";
};
/** Apply the persisted theme from AppSettings (the source of truth). */
export const syncThemeFromSettings = async (): Promise<void> => {
try {
const result = await commands.getAppSettings();
if (result.status === "ok") {
applyTheme(result.data.theme ?? "system");
}
} catch (e) {
console.warn("Failed to sync theme from settings:", e);
}
};
View on GitHub (pinned to c89b7bf389)
Solutions
- Call syncThemeFromSettings after the app/window ready event or once onboarding completes, not only at module import
- Verify the store plugin registration and capabilities include the settings command
- Guard browser dev with isTauri()
- Also handle result.status === "error" explicitly — an err status currently falls through with no log at all, which is the silent cousin of this warning
Example fix
// before
const result = await commands.getAppSettings();
if (result.status === "ok") {
applyTheme(result.data.theme ?? "system");
}
// after
const result = await commands.getAppSettings();
if (result.status === "ok") {
applyTheme(result.data.theme ?? "system");
} else if (result.status === "error") {
console.warn("getAppSettings returned error, keeping default theme:", result.error);
} Defensive patterns
Strategy: retry
Validate before calling
import { isTauri } from "@tauri-apps/api/core";
if (!isTauri()) return; Try / catch
try {
const result = await commands.getAppSettings();
if (result.status === "ok") applyTheme(result.data.theme ?? "system");
else console.warn("getAppSettings error status:", result.error);
} catch (e) { console.warn("Failed to sync theme from settings:", e); } Prevention
- Run theme sync after ready, not only at module import
- Handle both the err status and the rejected promise — the current code ignores one and warns the other
- Guard browser dev with isTauri()
When it happens
Trigger: Calling syncThemeFromSettings before the Tauri backend/store plugin is ready; the getAppSettings command not registered; running the frontend in a plain browser where invoke rejects; a settings-store file that fails to parse so the command rejects rather than returning an error status.
Common situations: Startup ordering issues when the module runs at import time; plugin/capability misconfigurations; dev iteration in Vite; migrated or corrupted settings files after schema changes.
Related errors
- Failed to sync language from settings:
- Failed to check Windows microphone permissions:
- Failed to show main window for permission onboarding:
- Failed to fetch secure input status:
- error while building tauri application
AI-assisted analysis of cjpais/Handy@c89b7bf389 (2026-08-17).
Data as JSON: /api/errors/5922f5b20303e555.
Report an issue: GitHub.