jlcodes99/cockpit-tools · error

保存账号失败: {}

Error message

保存账号失败: {}

What it means

Once user info and tokens are collected, start_oauth_login persists the account via modules::upsert_account(email, display_name, token_data). This error is logged and returned when the upsert fails, meaning the OAuth authorization succeeded but the account could not be saved to local storage.

Source

Thrown at src-tauri/src/commands/oauth.rs:103

    ));

    let token_data = models::TokenData::new(
        token_res.access_token,
        refresh_token,
        token_res.expires_in,
        Some(user_info.email.clone()),
        None,
        user_info.id.clone(),
    )
    .with_oauth_metadata(token_res.oauth_client_key, token_res.id_token);

    let mut account = modules::upsert_account(
        user_info.email.clone(),
        user_info.get_display_name(),
        token_data,
    )
    .map_err(|e| {
        modules::logger::log_error(&format!("保存账号失败: {}", e));
        e
    })?;

    modules::account::apply_account_note_after_oauth(
        &mut account,
        modules::account::AccountNoteUpdate {
            note,
            two_factor_secret,
            account_password,
            phone_number,
            mail_url,
            aux_email,
        },
    )?;
    let account = refresh_account_quota_after_login(account).await;

    modules::logger::log_info(&format!("账号添加成功: {}", account.email));

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Check disk space and write permissions on the app's data directory, then retry the login
  2. Close other running instances of the app that may hold a lock on the account store
  3. Back up and remove/repair a corrupted account store file, then re-run OAuth
  4. Update the app if the failure started after a version change (token_data schema migration issue)

Example fix

// before
let mut account = modules::upsert_account(user_info.email.clone(), user_info.get_display_name(), token_data)
    .map_err(|e| {
        modules::logger::log_error(&format!("保存账号失败: {}", e));
        e
    })?;
// after
let mut account = modules::upsert_account(user_info.email.clone(), user_info.get_display_name(), token_data)
    .map_err(|e| {
        modules::logger::log_error(&format!("保存账号失败: {}", e));
        format!("保存账号失败(请检查磁盘空间与数据目录权限): {}", e)
    })?;
Defensive patterns

Strategy: validation

Validate before calling

// check storage health before running the whole OAuth flow
if !is_dir_writable(&app_data_dir()) {
    return Err("应用数据目录不可写,请检查权限".to_string());
}
if free_disk_bytes(&app_data_dir())? < MIN_REQUIRED_BYTES {
    return Err("磁盘空间不足,无法保存账号".to_string());
}
if account_store_locked() {
    return Err("账号存储被其他实例占用,请关闭其他窗口后重试".to_string());
}

Try / catch

let mut account = match modules::upsert_account(user_info.email.clone(), user_info.get_display_name(), token_data) {
    Ok(a) => a,
    Err(e) => {
        log_error(&format!("保存账号失败: {}", e));
        return Err(format!("保存账号失败(请检查磁盘空间与数据目录权限): {}", e));
    }
};

Prevention

When it happens

Trigger: upsert_account returns Err: local storage/DB write failure (locked database, disk full, permission-denied store file), serialization failure of token_data, or a uniqueness/constraint violation on the email key.

Common situations: Disk full or read-only app data directory; corrupted or locked local account store (another instance running); schema change after an app update making stored token_data incompatible; antivirus locking the data file.

Related errors


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/a7851bda2efc7691. Report an issue: GitHub.