fix(chat-provider): preserve refreshed OAuth token on connection recovery - #2004
Conversation
…very When OAuth refreshes the access token, `_apply_access_token()` updates `client.api_key` but not `self._api_key`. If a transient network error triggers `on_retryable_error()` to rebuild the OpenAI client, it uses the stale `self._api_key` — a token that the server has already invalidated upon issuing the new one — causing 401 errors. Fix: read `api_key` from the current live client instead of the cached `self._api_key` in `on_retryable_error()`, and keep `self._api_key` in sync. Fixes MoonshotAI#1971
There was a problem hiding this comment.
Pull request overview
Fixes a connection-recovery authentication bug in the Kosong Kimi chat provider where OAuth token refresh updates the live OpenAI client’s api_key, but a retry-triggered client rebuild previously reused a stale cached key, leading to intermittent 401s (notably in TUN mode).
Changes:
- Update
Kimi.on_retryable_error()to rebuild the client usingold_client.api_keyand syncself._api_key. - Add regression tests covering refresh+retry cycles and an end-to-end Authorization header assertion via
respx. - Add changelog entries (root + package + docs).
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/kosong/src/kosong/chat_provider/kimi.py | Rebuilds the OpenAI client using the currently-active api_key to avoid stale-token 401s after refresh. |
| packages/kosong/tests/test_kimi_stale_api_key.py | Adds regression + E2E tests to confirm the rebuilt client sends the refreshed Bearer token. |
| CHANGELOG.md | Documents the user-visible fix in the root Unreleased changelog. |
| packages/kosong/CHANGELOG.md | Records the provider-specific fix in the Kosong package changelog. |
| docs/en/release-notes/changelog.md | Updates the English docs changelog entry (but this file is generated). |
| docs/zh/release-notes/changelog.md | Adds the corresponding Chinese release note entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| ## Unreleased | ||
|
|
||
| - Kosong: Fix stale API key after OAuth token refresh in Kimi provider — `on_retryable_error` now reads the current `api_key` from the live client instead of the cached `_api_key`, so that OAuth token refreshes applied via `client.api_key` are preserved when the client is rebuilt after a retryable error |
There was a problem hiding this comment.
docs/en/release-notes/changelog.md is auto-generated from the root CHANGELOG.md via docs/scripts/sync-changelog.mjs (see docs/AGENTS.md). To avoid the doc page drifting, please regenerate it with npm run sync / make gen-docs rather than editing this file directly (and ensure the committed output matches the root changelog).
There was a problem hiding this comment.
@copilot apply changes based on this feedback
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Fixes #1971
Root Cause
When OAuth refreshes the access token,
_apply_access_token()updatesclient.api_keybut notself._api_key. If a transient network error triggerson_retryable_error()to rebuild the OpenAI client, it uses the staleself._api_key— a token that the server has already invalidated upon issuing the new one — causing 401 errors.Fix
Read
api_keyfrom the current live client instead of the cachedself._api_keyinon_retryable_error():Why TUN mode triggers this
TUN mode causes occasional network route changes that interrupt established HTTP connections, triggering
APIConnectionError→on_retryable_error(). Without TUN mode, connections are stable andon_retryable_error()is never called, so the bug remains latent. After this fix, TUN mode usage no longer produces 401 errors.Testing
test_kimi_stale_api_key.py:Authorizationheader viarespxmock, confirms rebuilt client sends the refreshed tokenChecklist
make gen-changelogto update the changelog.make gen-docsto update the user documentation.