MoonshotAI / MoonshotAI/kimi-code

`kimi rc` silently exits 0 for env-scoped (global region) logins; startup errors are swallowed

Open
#3,581 2 comments 0 reactions 0 assignees View on GitHub

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.41.0 (kimi --version, linux-x64, Node SEA)

Which open platform/subscription were you using?

kimi-code, global region (/login → Kimi Code, auth.kimi.ai / api.kimi.ai/coding/v1)

Which model were you using?

kimi-for-coding (not relevant to this bug)

What platform is your computer?

Linux 5.10.0-41-amd64 x86_64 GNU/Linux

What issue are you seeing?

kimi rc (and kimi web --remote-control) always exits 0 with no output for global-region logins, right after the local server starts:

{"msg":"Server listening at http://127.0.0.1:58627"}
{"msg":"server ready"}
<process exits 0, nothing else printed>

No access URL, no QR code, no error message. Both bugs below reproduce on current main (af81bb9).

Bug 1 — Remote Control reads the OAuth token from the wrong credential slot.
apps/kimi-code/src/cli/sub/web/remote-control.ts:298 calls
resolveKimiTokenStorageName({ providerName: KIMI_CODE_PROVIDER_NAME }) with no oauthKey, so it loads the default slot credentials/kimi-code.json. But env-scoped logins (any oauthHost/baseUrl outside the shared defaults, i.e. all global-region kimi.ai logins) are stored by resolveKimiCodeOAuthKey in credentials/kimi-code-env-<sha256[:16]>.json. The default slot does not exist → throw new Error('Remote Control requires a Kimi login. Run kimi login first.') even though the user is logged in and normal sessions work.

Bug 2 — the startup error is swallowed: silent exit 0 instead of the error message.
When the onReady hook throws, apps/kimi-code/src/cli/sub/web/run.ts:406 catches, runs onShutdown('startup_failed'), closes the server, and rethrows — the rethrow should reach the command action's catch (run.ts:178) which prints to stderr and process.exit(1). It never does: the event loop drains and the process exits 0 silently.

Evidence (instrumented run of the app's own SEA bundle under Node 20):

!!! onReady enter
!!! onReady THREW: Error: Remote Control requires a Kimi login. Run `kimi login` first.
!!! running.close() called      <- catch path runs
!!! Server.close() called
!!! beforeExit 0                <- loop drains
!!! exit event 0                <- no stderr message, no process.exit(1)

Verified against the real v0.41.0 binary with strace/ptrace: server binds + listens; onReady throws before the relay is ever contacted (no DNS/connect to the relay, no server/rc.json lock); the fastify server is closed; exit_group(0) from the main thread.

What steps can reproduce the bug?

  1. kimi login → pick the global Kimi Code platform (.ai endpoints) — token is stored as ~/.kimi-code/credentials/kimi-code-env-<hash>.json.
  2. export KIMI_CODE_EXPERIMENTAL_FLAG=1 (or KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL=1)
  3. kimi rc --no-open
  4. Observe: only the "server ready" log lines, then silent exit 0.

A/B proof of Bug 1 (only variable is the credential file):

cp ~/.kimi-code/credentials/kimi-code-env-*.json ~/.kimi-code/credentials/kimi-code.json
kimi rc --no-open   # → "Kimi Remote Control ready", QR, relay connection
# remove kimi-code.json → back to silent exit 0

What is the expected behavior?

  1. kimi rc finds the credential for the current runtime environment (same slot resolution as login: resolveKimiCodeRuntimeAuth / resolveKimiCodeOAuthRef), and
  2. if startup fails, the error is printed to stderr and the exit code is non-zero — per the existing intent in run.ts (action catch writes the message + process.exit(1)).

Additional information

Suggested fixes:

  • Bug 1: in startRemoteControl, resolve the runtime OAuth ref from the configured oauthHost/baseUrl (as login does) and pass its key to resolveKimiTokenStorageName({ oauthKey }), instead of the hard-coded default slot.
  • Bug 2: write the error to stderr (or logger.error) inside the onReady catch before closing, and/or set process.exitCode = 1 synchronously so a natural event-loop drain cannot mask the failure.

Related (not a code bug): the default relay code-rc.kimi.com resolves to a single DDoS-scrubbing IP (103.143.17.156, block 103.143.16.0/23 netname HJ-HIDDOS / hiddos.cn, CN) that some ISPs silently drop (TCP 443 connect times out). The Cloudflare-fronted https://code-rc.kimi.ai serves the same relay ("welcome to kfc-relay"). Consider documenting KIMI_CODE_REMOTE_CONTROL_RELAY_URL and/or publishing both relay hostnames.

Workaround for global-region users until fixed:

cp ~/.kimi-code/credentials/kimi-code-env-*.json ~/.kimi-code/credentials/kimi-code.json
export KIMI_CODE_REMOTE_CONTROL_RELAY_URL=https://code-rc.kimi.ai   # only if code-rc.kimi.com is unreachable
kimi rc

Verified working end-to-end with both steps: ✓ Connected to relay, waiting for remote devices….

Contribution

  • I am willing to submit a PR for this bug fix myself (please wait for maintainer approval in this issue first)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with apps/kimi-code/src/cli/sub/web/remote-control.ts around line 298 and compare its credential resolution with the login paths named in the issue. Then inspect apps/kimi-code/src/cli/sub/web/run.ts around lines 178 and 406 to trace startup failure handling. Done means env-scoped logins work with remote control and startup errors reach stderr with a non-zero exit code.

Written by the indexing model from the issue text.

Assessment

Tech stack
nodejs, typescript
Domain
authentication, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.