MoonshotAI / MoonshotAI/kimi-code

installer: the kimi.bak rollback backup is deleted by the next CLI launch

Open
#3,904 1 comment 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

Summary

The native installer backs up the existing binary as <install_dir>/bin/kimi.bak and tells the user it did so — but the next kimi launch deletes exactly that file. The rollback point the installer just advertised does not survive one run of the CLI.

Why

install.sh (https://code.kimi.com/kimi-code/install.sh):

if [ -f "${KIMI_INSTALL_DIR}/bin/kimi" ]; then
  cp "${KIMI_INSTALL_DIR}/bin/kimi" "${KIMI_INSTALL_DIR}/bin/kimi.bak"
  _log "Backed up existing kimi to ${KIMI_INSTALL_DIR}/bin/kimi.bak"
fi

The CLI's self-update uses the same path as its own swap scratch (apps/kimi-code/src/cli/update/native-swap.ts:579: let bakPath = \${deps.exePath}.bak``), and its startup hygiene wipes every such file:

// native-swap.ts:341 — cleanupBackups()
if (!entry.startsWith(`${base}.`) || !entry.endsWith('.bak')) continue;
const middle = entry.slice(base.length + 1, -'.bak'.length);
if (middle !== '' && !/^\d+$/.test(middle)) continue;   // '' (kimi.bak) and <digits> both pass
await unlink(full).catch(() => {});

called from the startup sweep with no keepPath:

// native-swap.ts:421 — sweepStaleNativeUpdateArtifacts()
await cleanupBackups(exePath);

The function's own comment calls the targets "leftover .bak siblings of the exe from earlier swaps/installs" — i.e. the installer-created file is treated as debris by design. Note the swap success path does keep its backup (cleanupBackups(deps.exePath, bakPath)), but the next startup's sweep has no keepPath, so that one is removed as well.

Repro (linux, native install)
curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash   # prints "Backed up existing kimi to …/bin/kimi.bak"
ls ~/.kimi-code/bin/            # kimi  kimi.bak
kimi --version                  # any invocation, including this one
ls ~/.kimi-code/bin/            # kimi            ← kimi.bak is gone

Name-matched, not a general wipe — with dummy files in the same directory:

before: kimi.bak  kimi.20260101.bak  other.bak
after `kimi --version`:              other.bak      ← only the two matching names are removed
Impact

A user who wants to go back to the previous version after an upgrade follows the installer's message, looks for kimi.bak, and finds nothing. The only reliable recovery is re-running the installer with an explicit version.

Possible fixes
  • Have install.sh use a name the CLI never claims (e.g. kimi.bak.<version> / <timestamp>), or
  • make the startup sweep keep the newest <exe>.bak instead of deleting every match (keepPath already exists for the swap path), or
  • state in the installer output that this backup is transient.

cc @liruifengv (native-swap / update)

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

Read install.sh alongside apps/kimi-code/src/cli/update/native-swap.ts, especially cleanupBackups(), sweepStaleNativeUpdateArtifacts(), and the swap backup path. Reproduce the install, launch kimi once, and inspect the install directory. Done means the installer-advertised rollback backup survives the next CLI launch without breaking native update cleanup.

Written by the indexing model from the issue text.

Assessment

Tech stack
shell, typescript
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.