What version of Kimi Code is running?
0.35.0
Which open platform/subscription were you using?
Kimi Code (OAuth)
Which model were you using?
K3
What platform is your computer?
Darwin 25.3.0 arm64 arm
What issue are you seeing?
TL;DR
The Bash tool applies its cwd parameter by textually prepending cd '' && to the user's command. If the command's first line ends with &, shell operator precedence (&& binds tighter than &) sends the entire chain — including the cd — into a background subshell. The main shell never changes directory, so all following lines of the script run in the wrong directory. Nothing is reported; the cwd parameter is silently ignored.
What the caller expects
The caller's mental model: the whole script runs with /repo/packages/ui as its working directory — server.js in the background, check.js in the foreground, both in that directory.
What actually runs
The harness prepends the cd, producing:
cd '/repo/packages/ui' && node server.js &
sleep 1
node check.js
Bash parses line 1 as "background the whole cd ... && node server.js list". The cd happens inside the background subshell and has no effect on the main shell. So:
- node server.js — background, correct directory (output even looks right, e.g. it prints paths from the requested cwd);
- node check.js — foreground, original default directory (e.g. the repo root).
The asymmetry is the nasty part: the visible output suggests everything worked, while the foreground half of the script silently ran somewhere else. In practice this surfaced as Cannot find module errors with a require stack pointing at a completely different directory tree than the requested cwd, plus orphaned background processes the script's own kill %1 couldn't reach.
Evidence from a real session wire log
Anonymized excerpt from wire.jsonl — the tool call and its result (paths shortened):
The backgrounded server correctly started from /repo/.worktrees/feature-x/... (it inherited the cd), while the foreground node -e resolved modules from /repo — the harness's default cwd. The requested cwd never applied to it.
What steps can reproduce the bug?
mkdir -p /tmp/kimi-cwd-repro
Then, via the Bash tool with cwd set to /tmp/kimi-cwd-repro:
sleep 0.1 & echo "foreground cwd: $(pwd)"; wait
Expected: foreground cwd: /tmp/kimi-cwd-repro
Actual: the foreground pwd prints the caller's original working directory.
What is the expected behavior?
No response
Additional information
Suggested fix
Apply cwd as a real working directory of the spawned process (e.g. spawn(shell, { cwd })) instead of string-prepending cd. The cwd parameter is part of the tool's contract and should hold regardless of what shell syntax the command contains (&, ||, subshells, etc.).
If that's not feasible, a stopgap would be to detect commands whose first line ends with & and warn or reject, steering the caller to the tool's native run_in_background mechanism.
What version of Kimi Code is running?
0.35.0
Which open platform/subscription were you using?
Kimi Code (OAuth)
Which model were you using?
K3
What platform is your computer?
Darwin 25.3.0 arm64 arm
What issue are you seeing?
TL;DR
The Bash tool applies its cwd parameter by textually prepending cd '' && to the user's command. If the command's first line ends with &, shell operator precedence (&& binds tighter than &) sends the entire chain — including the cd — into a background subshell. The main shell never changes directory, so all following lines of the script run in the wrong directory. Nothing is reported; the cwd parameter is silently ignored.
What the caller expects
The caller's mental model: the whole script runs with /repo/packages/ui as its working directory — server.js in the background, check.js in the foreground, both in that directory.
What actually runs
The harness prepends the cd, producing:
Bash parses line 1 as "background the whole cd ... && node server.js list". The cd happens inside the background subshell and has no effect on the main shell. So:
The asymmetry is the nasty part: the visible output suggests everything worked, while the foreground half of the script silently ran somewhere else. In practice this surfaced as Cannot find module errors with a require stack pointing at a completely different directory tree than the requested cwd, plus orphaned background processes the script's own kill %1 couldn't reach.
Evidence from a real session wire log
Anonymized excerpt from wire.jsonl — the tool call and its result (paths shortened):
The backgrounded server correctly started from /repo/.worktrees/feature-x/... (it inherited the cd), while the foreground node -e resolved modules from /repo — the harness's default cwd. The requested cwd never applied to it.
What steps can reproduce the bug?
Then, via the Bash tool with cwd set to /tmp/kimi-cwd-repro:
Expected: foreground cwd: /tmp/kimi-cwd-repro
Actual: the foreground pwd prints the caller's original working directory.
What is the expected behavior?
No response
Additional information
Suggested fix
Apply cwd as a real working directory of the spawned process (e.g. spawn(shell, { cwd })) instead of string-prepending cd. The cwd parameter is part of the tool's contract and should hold regardless of what shell syntax the command contains (&, ||, subshells, etc.).
If that's not feasible, a stopgap would be to detect commands whose first line ends with & and warn or reject, steering the caller to the tool's native run_in_background mechanism.