User report
Surfaced via Telegram by the same community user who filed #586 (macOS Sequoia 15.7.3, deepseek 0.8.9, installed via cargo install):
Love your TUI! But have some issues here. (1) the colors are off [#586], and (2) it seems even with the api input, it does not connect to the actual server (no response).
The colors are #586. This issue is for the second symptom: the user typed their API key into the TUI onboarding, but the TUI behaves as if no key is set — turns hang or fail to connect.
Hypothesised root cause
crates/secrets/src/lib.rs documents the resolution order as:
Hard rule: keyring → env → config-file. Never swap.
Meanwhile the TUI onboarding's submit_api_key (crates/tui/src/tui/app.rs:1244) calls save_api_key (crates/tui/src/config.rs:2185), which writes only to ~/.deepseek/config.toml — it does not touch the OS keyring:
pub fn save_api_key(api_key: &str) -> Result<SavedCredential> {
// ...
let path = save_api_key_to_config_file(trimmed)?;
Ok(SavedCredential::ConfigFile(path))
}
So a user whose flow looks like this will silently miss the new key:
- At any point in the past, the user ran
deepseek auth set → an API key landed in the macOS Keychain under our service id.
- The key later becomes invalid (rotated upstream, account changed, key is from a previous DeepSeek-TUI installation, etc.).
- The user runs the TUI, sees the onboarding prompt, types a fresh key.
submit_api_key writes it to ~/.deepseek/config.toml.
- At request time, the keyring lookup hits the stale entry and short-circuits before the config file is consulted.
- The API call uses the old/invalid key → 401 → user-visible: "no response."
Same trap if a user installed an older DeepSeek-TUI build and then upgraded — the old keyring entry survives the upgrade.
Repro plan
Proposed fixes (in increasing scope)
- Make
submit_api_key keyring-aware. When the user re-enters a key during onboarding (or via /config api_key), also write it to the keyring slot — overwriting any stale entry. Documented behavior already says keyring is the source of truth, so save_api_key writing only to the config file is the bug. (small)
- Surface conflicts. If the keyring already holds a different key when onboarding starts, detect this and either ask the user "Replace stored key?" or just announce that we're overwriting it. (medium)
deepseek doctor should already check this; if it doesn't, add a check that flags "keyring has key X but config.toml has key Y; resolution will use X." Make the discrepancy visible when the user reports issues. (small/medium)
v0.8.11 acceptance criteria
References
crates/secrets/src/lib.rs — keyring backend + the documented resolution order.
crates/tui/src/config.rs:2180-2193 — save_api_key writes only to config file.
crates/tui/src/tui/app.rs:1244-1259 — submit_api_key (TUI onboarding entry).
crates/tui/src/tui/ui.rs:1631-1685 — onboarding state machine + engine respawn.
crates/cli/src/lib.rs:578 — no_keyring_secrets() (the bypass used in CLI flows).
Reporter
Same community user as #586, via Telegram on 2026-05-04. Worth a follow-up comment on #586 acknowledging the keyring symptom as a separate fix once we ship.
User report
Surfaced via Telegram by the same community user who filed #586 (macOS Sequoia 15.7.3,
deepseek 0.8.9, installed viacargo install):The colors are #586. This issue is for the second symptom: the user typed their API key into the TUI onboarding, but the TUI behaves as if no key is set — turns hang or fail to connect.
Hypothesised root cause
crates/secrets/src/lib.rsdocuments the resolution order as:Meanwhile the TUI onboarding's
submit_api_key(crates/tui/src/tui/app.rs:1244) callssave_api_key(crates/tui/src/config.rs:2185), which writes only to~/.deepseek/config.toml— it does not touch the OS keyring:So a user whose flow looks like this will silently miss the new key:
deepseek auth set→ an API key landed in the macOS Keychain under our service id.submit_api_keywrites it to~/.deepseek/config.toml.Same trap if a user installed an older DeepSeek-TUI build and then upgraded — the old keyring entry survives the upgrade.
Repro plan
deepseek_secrets::DefaultKeyringStore::get()resolves before~/.deepseek/config.tomlfor the engine's HTTP client. Trace the actual call path fromsubmit_api_key→ engine respawn → request build.service = "deepseek-tui-deepseek"(or whatever our service id is — checkcrates/secrets/src/lib.rs) and a bad API key, then rundeepseekand onboard with a different (good) key. Observe whether the request uses the keyring's bad key.Proposed fixes (in increasing scope)
submit_api_keykeyring-aware. When the user re-enters a key during onboarding (or via/config api_key), also write it to the keyring slot — overwriting any stale entry. Documented behavior already says keyring is the source of truth, sosave_api_keywriting only to the config file is the bug. (small)deepseek doctorshould already check this; if it doesn't, add a check that flags "keyring has key X but config.toml has key Y; resolution will use X." Make the discrepancy visible when the user reports issues. (small/medium)v0.8.11 acceptance criteria
~/.deepseek/config.toml. New keys take effect on the next turn without requiring a manualkeychainpurge.deepseek doctor, a stale-keyring-vs-config mismatch is reported as a warning with copy-paste remediation steps.deepseek auth setand never touched the TUI onboarding.References
crates/secrets/src/lib.rs— keyring backend + the documented resolution order.crates/tui/src/config.rs:2180-2193—save_api_keywrites only to config file.crates/tui/src/tui/app.rs:1244-1259—submit_api_key(TUI onboarding entry).crates/tui/src/tui/ui.rs:1631-1685— onboarding state machine + engine respawn.crates/cli/src/lib.rs:578—no_keyring_secrets()(the bypass used in CLI flows).Reporter
Same community user as #586, via Telegram on 2026-05-04. Worth a follow-up comment on #586 acknowledging the keyring symptom as a separate fix once we ship.