[Bug] 一直报错Indexing policy changed

オープン
#1,749 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@AACS111 がすでに取り組んでいます。

2026年11月6日 から。

  • #1773 @AACS111 による — オープン

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
java, typescript
領域
backend, devtools

調査の方向性

Start with the reported language and application logs under logs/language and logs/application, then trace the workspace indexing policy failure in the LSP startup path; the report names lsp-core-adapter-*.js but gives no source file or test. Reproduce with the described Windows 11, 16-module Maven workspace and automatic Java project import. Done means Java LSP startup completes without repeated “Indexing policy changed” cancellations.

索引モデルが issue の本文から書いたものです。

説明

bug issue-form:bug review: low

[Bug] Windows: "Indexing policy changed" 反复取消 Java LSP 启动,Java 语言服务始终无法就绪

环境

项 值
Lithe 版本 0.6.7(Windows x64,正式版,2026-11-04 构建)
系统 Windows 11 专业版 build 26300(64 位)
JDK 使用 Lithe 自带的 JDT LS + 内置 JDK(LanguageServers/jdk),未自定义
工程类型 Maven 多模块(16 个模块,约 630 个 .java,工作区约 26 MB,依赖全部来自本地仓库)
相关设置 索引设置为默认值(Git 忽略开启、无手动排除);autoSave = true;javaProjectImportOnOpen = "automatic";单窗口、单工作区
日志级别 默认(<app_local_data_dir>/logs/{application,language})

单次失败耗时分布(最新会话,毫秒):6072, 9391, 12152, 13250, 14683, 27327, 30999, 31772, 39284, 41519, 75028, 94725, 113480, 114143, 130464, 136063, 140129, 144482, 161339, 231036, 253610, 261048, 285503。可见耗时跨度从 6 秒到近 5 分钟,越往后越接近“导入已接近完成时被打断”。

关键日志片段(已脱敏)

Language 日志(logs/language/lithe.*.log):

 02:13:11.320 ERROR [scope=runtime.console] Failed to read workspace indexing policy for file change: IndexingSettingsError: configureFailed
 02:13:11.310 INFO [scope=lsp.lifecycle] javaWorkspaceDetection:started language_id=java outcome=started
 02:13:12.100 INFO [scope=lsp.lifecycle] sessionStart:started language_id=java provider_id=java outcome=started
 02:13:43.119 ERROR [scope=lsp.lifecycle] sessionStart:failed duration_milliseconds=30999
                    error="Indexing policy changed" error_code=cancelled language_id=java
                    operation=sessionStart provider_id=java stage=processStart outcome=failed
 02:13:43.120 ERROR [scope=editor.LSPClient] Failed to start LSP for file:
                    detail="Error: Indexing policy changed   at .../assets/lsp-core-adapter-*.js"
 02:13:43.120 ERROR [scope=editor.LspIntegration] LSP initialization failed

Application 日志(logs/application/lithe.*.log),同一时刻还有一组“工作区会话关闭”的连带错误:

 02:13:43.908 ERROR [scope=runtime.console] [fff] workspace sync failed: Error: Workspace window closed
 02:13:11.310 WARN [scope=runtime.console] MyBatis index failed: Error: Workspace window closed
 02:13:11.310 WARN [scope=runtime.console] Spring index failed: indexFailed

以及工程打开当刻就已经失败过一次:

 02:13:11.320 ERROR [scope=runtime.console] Failed to read workspace indexing policy for file change: IndexingSettingsError: configureFailed
 02:13:11.310 INFO [scope=workspace-open] setProjectRoot:end duration_ms=38340

源码定位(0.6.7 / main)

1. 消息来源:rust/lithe-core/src/project/indexing.rs

 // 发布阶段:代次已被替换
 if !entries.get(&root).is_some_and(|current| Arc::ptr_eq(current, &context)) {
     return Err(CoreError::new(ErrorCode::Cancelled, "Indexing policy changed"));
 }
 ​
 // 检查点:代次已退役
 impl IndexingContext {
     pub(crate) fn check(&self) -> Result<(), CoreError> {
         crate::protocol::cancellation::check()?;
         if self.retired.load(Ordering::Acquire) {
             return Err(CoreError::new(ErrorCode::Cancelled, "Indexing policy changed"));
        }
         Ok(())
    }
 }

这条路径上有四个地方会退役当前代次:

  • configure() / configure_with_provider_update()(策略不同、refresh = true,或旧代次已退役时新建代次并 retired.store(true));

  • refresh_indexing()(workspace.refreshIndexing,安装 refreshed_context 并退役旧代次);

  • refresh()(文件监听侧刷新,同样退役旧代次);

  • release_lease()(最后一个租约释放后退役)。

2. LSP 启动与索引策略的耦合点:prepare_provider_exclusions() 在给 provider 下发新代次前调用 context.check()?,命中退役即返回上面的 Cancelled;而 sessionStart 把这个错误直接当作启动失败处理,没有重取最新代次重试。

3. 前端重试覆盖不全:windows/tauri/src/features/file-explorer/stores/workspace-indexing.ts 只对 workspace.configureIndexing / workspace.refreshIndexing 的 cancelled 做了有限重试(supersededRetries < 2),LSP 启动链路没有对应处理,三次尝试用尽后原始错误被弹成通知。

推测根因

JDT 冷启动(Maven 导入 + 依赖解析)耗时很长(本例 6 秒 ~ 285 秒)。在此期间只要有任意一处重新安装索引策略,正在进行的 sessionStart 就会在检查点被判为 Cancelled,整段启动作废并重来;重来又会再次与下一次策略刷新撞上,形成稳定复现的循环,因此 Java 语言服务永远不会就绪。

从日志时序看,javaWorkspaceDetection:started、前端 configureFailed 与 sessionStart:started 出现在同一毫秒级窗口,且失败时同时出现 Workspace window closed(Spring/MyBatis 索引、工作区同步同时被取消),更像是启动期存在多路并发(Java 检测侧的排除项安装 + UI 侧索引策略刷新 + 工作区会话生命周期)互相作废,而不是单一调用方的问题。

建议的修复方向

  1. prepare_provider_exclusions() / sessionStart 命中 ErrorCode::Cancelled + "Indexing policy changed" 时不要整体失败,改为重新读取当前 context 后用最新策略继续(与前端已有的“重读设置并重试”策略一致)。

  2. 或者给 Java 冷启动加一个“策略代次稳定期”/背压:导入期间把策略重配排队,导入完成后再应用。

  3. UI 侧把这类“代次被替换”的内部取消降级(不弹红色错误通知),仅在最终重试耗尽时提示一次,并给出可操作文案(例如“索引配置在 Java 导入期间变化,已重新应用”)。

  4. 若上述时序确实是“Java 检测侧与 UI 侧策略不同导致乒乓”,建议两侧共享同一份策略来源(同一 owner / 同一 localStorage 键),避免互相退役。

影响

在 Windows 上打开较大的 Maven 多模块工程时,Java 语言服务 100% 无法启动(本机三次会话内 0 次成功),Java 相关功能全部不可用;同时通知中心被大量重复错误占据,用户无法判断这是否是严重故障。


说明:本报告中的 <WORKSPACE>、<app_local_data_dir> 及模块/包路径均为脱敏占位,原始日志中的用户名、工程名与业务包名已移除;时间戳、错误码、耗时、行号与源码引用保持原样。

主要言語
TypeScript
スター
1.8k
フォーク
151
平均マージ
11時間 41分
マージ済み PR(30日)
416

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

1lck/Lithe-IDEA のほかの issue

1lck/Lithe-IDEA の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。