MoonshotAI / MoonshotAI/kimi-code
[ACP] Non-auth provider failures such as quota 403 are swallowed as end_turn
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
What version of Kimi Code is running?
0.26.0 (@moonshot-ai/kimi-code@0.26.0, commit 36b05820cba24e09fdff19a059afc08ccea2c35e)
Which open platform/subscription were you using?
Kimi Code managed OAuth subscription with a billing-cycle usage quota.
Which model were you using?
kimi-code/k3
What platform is your computer?
Darwin 25.5.0 arm64 arm
What issue are you seeing?
When a provider request fails because the billing-cycle usage quota is exhausted, Kimi Code detects and logs the failure internally, but its ACP adapter resolves session/prompt successfully with stopReason: "end_turn".
The ACP client therefore receives no error and cannot tell the user that quota was exhausted. From the client side, the turn looks like an empty successful completion or a stalled conversation.
This is a quota failure, not an authentication or permission failure.
Internal Kimi Code log:
llm request failed ... errorName=APIStatusError errorMessage="403 You've reached your usage limit for this billing cycle. Your quota will be refreshed in the next cycle." statusCode=403
acp: turn ended with failed reason error={"code":"provider.api_error","name":"APIStatusError","details":{"statusCode":403,"turnId":2},"retryable":false}
ACP-observed result:
{
"stopReason": "end_turn"
}
No machine-readable provider or quota error reaches the ACP client.
What steps can reproduce the bug?
- Log in to Kimi Code using a quota-based managed subscription.
- Start Kimi Code as an ACP agent with
kimi acpand connect an ACP client. - Exhaust the billing-cycle quota.
- Send another prompt through the ACP client.
- Compare the Kimi Code log with the
session/promptJSON-RPC result.
Kimi Code logs a turn.ended event with reason: "failed" and a non-auth provider.api_error, while the ACP request resolves normally as end_turn. Repeating the prompt produces the same result.
What is the expected behavior?
A turn.ended event with reason: "failed" should be surfaced through the ACP/JSON-RPC error channel, with safe machine-readable fields such as the provider error code, HTTP status, and retryability. The ACP client should be able to display the quota message and mark the turn as failed.
It should not be converted into a successful end_turn. Authentication failures can keep their existing authRequired handling.
Additional information
The behavior appears to be explicitly implemented and covered by a test:
packages/acp-adapter/src/session.tsrejects authentication failures, but logs and resolves all otherturn.ended(reason="failed")events.packages/acp-adapter/src/events-map.tsmapsfailedtoend_turn.packages/acp-adapter/test/error-mapping.test.tscalls the non-auth behavior a “log-only path” and asserts that the request resolves.
The same path is still present on the current main branch. I could not find an existing issue that combines quota exhaustion with the ACP failure being swallowed as end_turn.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/acp-adapter/src/session.ts around the session/prompt handling, then inspect events-map.ts and packages/acp-adapter/test/error-mapping.test.ts. Run the error-mapping tests first to reproduce the existing log-only path. Done means non-auth failed turns reach the ACP/JSON-RPC error channel with safe provider details, while authentication failures retain their existing authRequired handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100