jlcodes99/cockpit-tools · warning
[SyncSettings] 保存合并后的配置失败: {}
Error message
[SyncSettings] 保存合并后的配置失败: {} What it means
During app setup in src-tauri/src/lib.rs run(), after merging default config language with system language, the code persists the merged language via modules::config::patch_user_config; failure is logged as '[SyncSettings] 保存合并后的配置失败: {e}'. It is non-fatal: startup continues, but the merged language is not persisted, so it will be re-derived (and possibly re-prompted) on next launch.
Source
Thrown at src-tauri/src/lib.rs:348
}
// 启动时同步设置合并(移至后台线程,不阻塞窗口显示)
std::thread::spawn(|| {
let current_config = modules::config::get_user_config();
if let Some(merged_language) = modules::sync_settings::merge_setting_on_startup(
"language",
¤t_config.language,
None,
) {
info!(
"[SyncSettings] 启动时合并语言设置: {} -> {}",
current_config.language, merged_language
);
if let Err(e) = modules::config::patch_user_config(|config| {
config.language = merged_language;
Ok(())
}) {
logger::log_error(&format!("[SyncSettings] 保存合并后的配置失败: {}", e));
}
}
});
// 启动 WebSocket 服务(使用 Tauri 的 async runtime)
tauri::async_runtime::spawn(async {
modules::websocket::start_server().await;
});
// 启动网页查询服务(网络服务配置中的独立模块)
tauri::async_runtime::spawn(async {
modules::web_report::start_server().await;
});
tauri::async_runtime::spawn(async {
modules::codex_local_access::restore_local_access_gateway().await;
});
View on GitHub (pinned to 1ed8b77992)
Solutions
- Read the inner e for the underlying config I/O or parse error.
- Ensure the user config directory exists and is writable before app setup (create dirs, fix permissions).
- If the config file is corrupted JSON, back it up and let the app regenerate defaults.
- Retry launching the app after closing other instances that may lock the config file.
Defensive patterns
Strategy: fallback
Validate before calling
// Before launch, ensure config dir is writable
const ok = await invoke('ensure_config_dir_writable').catch(() => false);
if (!ok) console.warn('config dir not writable; language sync will be skipped'); Type guard
function isSupportedLanguage(l: unknown): l is 'zh-CN' | 'en-US' {
return l === 'zh-CN' || l === 'en-US';
} Try / catch
try {
await invoke('patch_user_config', { patch: { language: mergedLanguage } });
} catch (e) {
// fall back to in-memory language only; do not block startup
console.warn('language not persisted; will re-merge on next launch', e);
} Prevention
- Create the config directory with correct permissions during install
- Parse config defensively and regenerate on corruption
- Serialize config writes during startup initialization
- Treat language persistence as best-effort, never fatal to startup
When it happens
Trigger: patch_user_config returns Err while writing config.language: config file read/parse failure, write permission denied, file locked, or disk full during first-launch language sync.
Common situations: First launch on a system where the config directory doesn't exist or isn't writable; config JSON corrupted from a previous crash; multiple app instances racing on the config file at startup.
Related errors
- 解析语言文件失败 {}: {}
- [WorkbuddyAutoCheckin] 保存配置到 Rust 后端失败:
- Failed to apply startup page preference:
- 加载 Codex API 服务速度失败:
- [Codex Auto-Restore] 恢复代理接管失败:
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/1b8fc354bf267305.
Report an issue: GitHub.