Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-model-auth-error-message.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---

Fix a misleading "OAuth login expired" message shown when a model is not available for the current account; the CLI now shows the provider's actual error.
7 changes: 6 additions & 1 deletion packages/agent-core/src/agent/compaction/full.ts
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,12 @@ export class FullCompaction {
thinking_effort: this.agent.config.thinkingEffort,
error_type: error instanceof Error ? error.name : 'Unknown',
});
if (isKimiError(error) && error.code === ErrorCodes.AUTH_LOGIN_REQUIRED) throw error;
if (
isKimiError(error) &&
(error.code === ErrorCodes.AUTH_LOGIN_REQUIRED ||
error.code === ErrorCodes.PROVIDER_AUTH_ERROR)
)
throw error;
throw new KimiError(ErrorCodes.COMPACTION_FAILED, String(error), { cause: error });
}
}
Expand Down
5 changes: 3 additions & 2 deletions packages/agent-core/src/session/provider-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,10 @@ export class ProviderManager implements ModelProvider {
} catch (error) {
if (!(error instanceof APIStatusError) || error.statusCode !== 401) throw error;
if (refreshed) {
const reason = error.message.replaceAll('\r', '');
throw new KimiError(
ErrorCodes.AUTH_LOGIN_REQUIRED,
'OAuth provider credentials were rejected. Send /login to login.',
ErrorCodes.PROVIDER_AUTH_ERROR,
reason.length > 0 ? reason : 'OAuth provider credentials were rejected.',
{
cause: error,
details: { statusCode: error.statusCode, requestId: error.requestId },
Expand Down
4 changes: 2 additions & 2 deletions packages/agent-core/test/agent/compaction/full.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ describe('FullCompaction', () => {
expect(messageText(compactionCall?.history[5])).toBe('lookup result');
});

it('force-refreshes OAuth credentials on compaction 401 and falls back to login_required when replay 401', async () => {
it('force-refreshes OAuth credentials on compaction 401 and treats replay 401 as provider auth error', async () => {
const tokenCalls: Array<boolean | undefined> = [];
const authKeys: string[] = [];
const oauthOptions = oauthTestAgentOptions(async (options) => {
Expand Down Expand Up @@ -398,7 +398,7 @@ describe('FullCompaction', () => {
expect.objectContaining({
event: 'error',
args: expect.objectContaining({
code: 'auth.login_required',
code: 'provider.auth_error',
details: expect.objectContaining({
statusCode: 401,
requestId: 'req-compact-401',
Expand Down
11 changes: 6 additions & 5 deletions packages/agent-core/test/agent/turn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1409,7 +1409,7 @@ describe('Agent turn flow', () => {
);
});

it('falls back to login_required when force-refresh and replay both 401', async () => {
it('treats 401 after force-refresh as provider auth error', async () => {
const tokenCalls: Array<boolean | undefined> = [];
const authKeys: string[] = [];
const oauthOptions = oauthAgentOptions(
Expand Down Expand Up @@ -1447,7 +1447,7 @@ describe('Agent turn flow', () => {
args: expect.objectContaining({
reason: 'failed',
error: expect.objectContaining({
code: 'auth.login_required',
code: 'provider.auth_error',
details: expect.objectContaining({
statusCode: 401,
requestId: 'req-401',
Expand Down Expand Up @@ -1644,7 +1644,7 @@ describe('Agent turn flow', () => {
expect(payloads[1]).toMatchObject({ turnStep: '0.1', attempt: '2/3' });
});

it('force-refreshes OAuth credentials on video upload 401 and falls back to login_required when replay 401', async () => {
it('force-refreshes OAuth credentials on video upload 401 and surfaces the provider auth error when replay 401', async () => {
const tokenCalls: Array<boolean | undefined> = [];
const authKeys: string[] = [];
const oauthOptions = oauthAgentOptions(
Expand Down Expand Up @@ -1689,8 +1689,9 @@ describe('Agent turn flow', () => {
expect(result.isError).toBe(true);
expect(authKeys).toEqual(['fresh-token', 'forced-refresh-token']);
expect(tokenCalls).toEqual([undefined, true]);
expect(result.output).toContain('OAuth provider credentials were rejected');
expect(result.output).toContain('Send /login to login');
expect(result.output).toContain('Unauthorized');
expect(result.output).not.toContain('OAuth provider credentials were rejected');
expect(result.output).not.toContain('Send /login to login');
});

it('cancels an active turn', async () => {
Expand Down
Loading