Skip to content

fix(tui): surface invalid additional directory errors - #4554

Open
YD-233 wants to merge 1 commit into
MoonshotAI:mainfrom
YD-233:fix/tui-invalid-additional-dir-errors
Open

YD-233 wants to merge 1 commit into
MoonshotAI:mainfrom
YD-233:fix/tui-invalid-additional-dir-errors

Conversation

@YD-233

@YD-233 YD-233 commented Oct 30, 2026

Copy link
Copy Markdown

Requirement or Bug

Resolve #4545.

当 .kimi-code/local.toml 中的 workspace.additional_dir 在本机不存在或不是目录时,TUI 会在用户接受 workspace trust 后静默退出。修复后,启动错误会正常显示,并包含导致失败的具体路径;print 模式和 ACP 等复用同一配置服务的入口也会得到更明确的错误信息。

Bug Reproduction Steps

See linked issue.

核心场景是:在 Git 项目中配置一个不存在的 workspace.additional_dir,启动 kimi 并接受 workspace trust。修改前进程没有可见错误文本并直接退出;kimi -p 能显示错误,但错误中没有无效路径。

Root Cause

无效目录使 WorkspaceDirsService.ready 拒绝后,后台初始化的三层 Promise 都可能在缺少及时消费者时产生 unhandledRejection:

  • WorkspaceDirsService 的本地配置 watcher;
  • WorkspaceRootSkillSource.watchReady;
  • WorkspaceSkillCatalogService.ready。

TUI 的全局 unhandledRejection 处理器会首先退出进程,使原始错误无法继续传播到 formatStartupError(),因此用户看不到任何诊断。

这是根本修复:为后台 Promise 链补上拒绝观察,避免未处理 rejection,同时保持原始 ready Promise 仍为 rejected。后续显式等待这些 Promise 的调用方仍会收到同一个配置错误,不会把无效配置静默当成成功。

另外,FileProjectLocalConfigService 原来对不存在、非目录和空值都返回同一条笼统消息,无法指出具体坏配置项。

Code Changes

 invalid additional_dir
   FileProjectLocalConfigService
-    throw CONFIG_INVALID without the path
+    throw CONFIG_INVALID with the resolved path
   WorkspaceDirsService.ready remains rejected
-    void ready.then(watchLocalToml)
+    ready.then(watchLocalToml, handleReadyRejection)
   WorkspaceRootSkillSource.watchReady remains rejected
+    void watchReady.catch(() => undefined)
   WorkspaceSkillCatalogService.ready remains rejected
+    void ready.catch(() => undefined)
   explicit awaiter receives the original error
   KimiTUI.start / runShell
   main.ts catch
   formatStartupError

这些拒绝处理只防止后台派生 Promise 抢先触发进程级 unhandledRejection,不会把 ready 转成成功,也不会让无效目录继续启动。

错误消息现在区分为:

workspace.additional_dir must exist and be a directory: /resolved/invalid/path
workspace.additional_dir must not be empty

阅读指南:先看 workspaceDirsService.ts 和两处 skill readiness 初始化,理解错误传播;再看 projectLocalConfigService.ts,理解错误文案。其余改动均为对应回归测试和 CLI changeset。

Screenshots / Recordings

接受 workspace trust 后的 TUI 可见结果:

Before After
没有可见错误文本,进程直接退出 error: failed to start shell: workspace.additional_dir must exist and be a directory: D:/project/does-not-exist

After 来自本 PR 源码的真实 TUI 运行;同时会打印日志文件路径,退出码为 1。

Behavior Changes and Affected Users

行为 修改前 修改后 依赖旧行为的人群 退路
TUI 遇到无效 additional_dir 接受 trust 后静默退出 显示包含无效路径的启动错误和日志位置,退出码仍为 1 无人依赖静默退出;受影响的是使用失效项目本地配置的 TUI 用户 修正配置;仍保持严格校验
print、ACP、SDK 等入口遇到不存在或非目录的 additional_dir 只显示笼统错误 显示解析后的具体无效路径 print 用户、ACP 客户端及 SDK 调用方;精确匹配旧错误文本的外部自动化可能受影响 错误码仍为 config.invalid,可匹配稳定错误码或消息前缀
空 additional_dir 配置项 报告“必须存在且为目录” 明确报告配置项为空 使用项目本地配置或 ACP additional directories 的调用方 同上
有效目录和其他配置、I/O 错误 按原路径处理 不变;ready 仍拒绝,原有错误继续传播 使用有效工作区配置的现有用户及既有错误处理方 无需

受影响模块与测试覆盖:

  • WorkspaceDirsService:新增无效本地配置回归,验证 watcher 不产生额外未处理拒绝,显式等待方仍收到原始错误。
  • Workspace skill catalog:新增延迟等待 ready 的回归,覆盖中间层和最外层 Promise 的未处理拒绝。
  • FileProjectLocalConfigService:覆盖不存在、指向普通文件和空值三类输入,并验证解析后的路径。
  • 既有 TUI startup、CLI main 和 run-shell 测试继续通过,覆盖启动错误传播与终端清理。
  • 未修改配置 schema、公开 API、ACP 能力矩阵、wire/session 格式、环境变量、prompt 或有效目录的处理逻辑。
验证记录
  • 相关核心测试:52 个通过。
  • 相关 CLI/TUI 测试:171 个通过。
  • pnpm lint:通过。
  • pnpm typecheck:通过。
  • changeset status:通过。
  • 真实 headless 验证:错误包含无效路径。
  • 真实 TUI 验证:接受 trust 后显示启动错误与日志路径,不再静默退出。
  • 未额外启动 ACP 客户端;ACP 与 print 复用已测试的共享配置服务。
  • 本机全仓 pnpm test 为 18,124 passed / 122 failed / 17 skipped。多数失败来自中文 checkout 路径导致 fixture URL 编码后不存在;抽查的 MCP 与 agent 超时失败在未修改的 HEAD 基线中同样复现。与本 PR 相关的测试没有失败。
  • 远端 CI 待运行。

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: issue must have a maintainer's /approve).
  • I have added tests that prove my feature works.
  • The behavior-change table above is complete, and every removed behavior or flipped default is named in the changeset and either has an escape hatch or was explicitly approved by a maintainer in this PR.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Oct 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c4fe642

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T08:35:25.757022Z c4fe642 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@pkg-pr-new

pkg-pr-new Bot commented Oct 30, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@c4fe642
npx https://pkg.pr.new/@moonshot-ai/kimi-code@c4fe642

commit: c4fe642

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TUI exits silently after trusting a workspace when .kimi-code/local.toml contains a non-existent additional_dir path

1 participant