-
Notifications
You must be signed in to change notification settings - Fork 178
Closed
Labels
Description
Environment
- Editor: Helix (version 25.07.1 (a05c151b))
- TypeScript version: 5.0.0
- Language Server: TypeScript LSP
Issue Description
The TypeScript language server frequently hangs when resolving completion details, specifically during foo.bar style autocompletion. The hang occurs in the interruptGetErr call and can last 15-32 seconds before timing out.
Reproduction Steps
- Open a TypeScript file in Helix
- Type
foo.to trigger completion - Select a completion item that requires detail resolution
- Hit enter
- Language server hangs for ~18 seconds
The issue appears to be in the completion resolution pipeline:
// src/lsp-server.ts
async completionResolve(item: lsp.CompletionItem, token?: lsp.CancellationToken): Promise<lsp.CompletionItem> {
// ...
const response = await this.tsClient.interruptGetErr(() =>
this.tsClient.execute(CommandTypes.CompletionDetails, cachedData, token)
);
// ...
}Personal debugging log . See time difference between startTime and endTime
{"serverState":1,"running":true,"errored":false,"none":false}
{"serverState":1,"running":true,"errored":false,"none":false}
{"command":"completionEntryDetails","cachedData":{"file":"/path/to/project/users-table/columns.tsx","line":14,"offset":26,"entryNames":["staticStatusText"]},"token":{"_isCancelled":false}}
{"startTime":"Wed Sep 24 2025 20:32:37 GMT+0000 (Greenwich Mean Time)"}
{"serverState":1,"running":true,"errored":false,"none":false}
{"serverState":1,"running":true,"errored":false,"none":false}
{"command":"completionEntryDetails","cachedData":{"file":"/path/to/project/users-table/columns.tsx","line":14,"offset":26,"entryNames":["staticStatusText"]},"token":{"_isCancelled":false}}
{"startTime":"Wed Sep 24 2025 20:32:37 GMT+0000 (Greenwich Mean Time)"}
{"serverState":1,"running":true,"errored":false,"none":false}
{"serverState":1,"running":true,"errored":false,"none":false}
{"endTime":"Wed Sep 24 2025 20:32:55 GMT+0000 (Greenwich Mean Time)"}
Returned item
{"data":{"file":"/path/to/project/users-table/columns.tsx","line":14,"offset":26,"entryNames":["staticStatusText"]},"kind":5,"label":"staticStatusText","sortText":"11","textEdit":{"insert":{"end":{"character":25,"line":13},"start":{"character":16,"line":13}},"newText":"staticStatusText","replace":{"end":{"character":25,"line":13},"start":{"character":16,"line":13}}},"detail":"(property) staticStatusText: (accessor: AccessorEntity<Transaction>, config: StatusColumnConfig) => ColumnDef<Transaction, unknown>","documentation":{"kind":"markdown","value":"Status column using Status component"}}
{"endTime":"Wed Sep 24 2025 20:32:55 GMT+0000 (Greenwich Mean Time)"}
Returned item
{"data":{"file":"/path/to/project/users-table/columns.tsx","line":14,"offset":26,"entryNames":["staticStatusText"]},"kind":5,"label":"staticStatusText","sortText":"11","textEdit":{"insert":{"end":{"character":25,"line":13},"start":{"character":16,"line":13}},"newText":"staticStatusText","replace":{"end":{"character":25,"line":13},"start":{"character":16,"line":13}}},"detail":"(property) staticStatusText: (accessor: AccessorEntity<Transaction>, config: StatusColumnConfig) => ColumnDef<Transaction, unknown>","documentation":{"kind":"markdown","value":"Status column using Status component"}}
{"serverState":1,"running":true,"errored":false,"none":false}
Logs from helix (~/.cache/helix/helix.log)
2025-09-24T21:46:40.643 helix_lsp::transport [INFO] typescript-language-server -> {"jsonrpc":"2.0","method":"completionItem/resolve","params":{"data":{"cacheId":31},"filterText":".staticStatusText","kind":5,"label":"staticStatusText","sortText":"11","textEdit":{"newText":".staticStatusText","range":{"end":{"character":16,"line":12},"start":{"character":15,"line":12}}}},"id":6}
2025-09-24T21:46:40.754 helix_lsp::transport [INFO] typescript-language-server -> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"range":{"end":{"character":22,"line":12},"start":{"character":15,"line":12}},"text":"."}],"textDocument":{"uri":"file:///file/path/users-table/columns.tsx","version":11}}}
2025-09-24T21:46:40.754 helix_lsp::transport [INFO] vscode-eslint-language-server -> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"range":{"end":{"character":22,"line":12},"start":{"character":15,"line":12}},"text":"."}],"textDocument":{"uri":"file:///file/path/users-table/columns.tsx","version":11}}}
2025-09-24T21:46:40.754 helix_lsp::transport [INFO] typescript-language-server -> {"jsonrpc":"2.0","method":"completionItem/resolve","params":{"data":{"cacheId":31},"filterText":".staticStatusText","kind":5,"label":"staticStatusText","sortText":"11","textEdit":{"newText":".staticStatusText","range":{"end":{"character":16,"line":12},"start":{"character":15,"line":12}}}},"id":7}
2025-09-24T21:46:40.754 helix_lsp::transport [INFO] tailwindcss-ls -> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"text":"import { Transaction } from '@shared/types/__generated_types__';\n\nimport { createColumnFactory } from '../../../shared-ui/table-columns';\n\nconst columnFactory = createColumnFactory<Transaction>();\n\nconst columns = [\n columnFactory.customer('customer', { header: 'Customer' }),\n columnFactory.amount('amount', { header: 'Amount' }),\n columnFactory.text('transactionType.name', {\n header: 'Transaction Type',\n }),\n columnFactory.('paymentMethodService'),\n columnFactory.statusByValue('transactionStatus.slug', {\n header: 'Status',\n }),\n columnFactory.date('createdAt', { header: 'Date' }),\n];\n\nexport default columns;\n"}],"textDocument":{"uri":"file:///file/path/users-table/columns.tsx","version":11}}}
2025-09-24T21:46:40.754 helix_lsp::transport [INFO] emmet-ls -> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"range":{"end":{"character":22,"line":12},"start":{"character":15,"line":12}},"text":"."}],"textDocument":{"uri":"file:///file/path/users-table/columns.tsx","version":11}}}
2025-09-24T21:46:41.260 helix_lsp::transport [INFO] tailwindcss-ls <- {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///file/path/users-table/columns.tsx","diagnostics":[]}}
2025-09-24T21:46:53.631 helix_lsp::transport [INFO] vscode-eslint-language-server <- {"jsonrpc":"2.0","method":"eslint/status","params":{"uri":"file:///file/path/users-table/columns.tsx","state":1}}
2025-09-24T21:46:57.917 helix_lsp::transport [INFO] typescript-language-server <- {"jsonrpc":"2.0","id":6,"result":{"data":{"file":"/file/path/users-table/columns.tsx","line":13,"offset":17,"entryNames":["staticStatusText"]},"filterText":".staticStatusText","kind":5,"label":"staticStatusText","sortText":"11","textEdit":{"newText":".staticStatusText","range":{"end":{"character":16,"line":12},"start":{"character":15,"line":12}}},"detail":"(property) staticStatusText: (accessor: AccessorEntity<Transaction>, config: StatusColumnConfig) => ColumnDef<Transaction, unknown>","documentation":{"kind":"markdown","value":"Status column using Status component"}}}
2025-09-24T21:47:00.757 helix_term::ui::completion [ERROR] Failed to resolve completion item: request 7 timed out
2025-09-24T21:47:00.757 helix_lsp::transport [INFO] typescript-language-server -> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"range":{"end":{"character":16,"line":12},"start":{"character":15,"line":12}},"text":".staticStatusText"}],"textDocument":{"uri":"file:///file/path/users-table/columns.tsx","version":12}}}
From the logs above, when the LSP hangs, it resorts to the following error from helix, based on my analysis (id 7)
2025-09-24T21:47:00.757 helix_term::ui::completion [ERROR] Failed to resolve completion item: request 7 timed out
Autocomplete example
- type
staticSta - select
staticStatusText - hit the
enter key.
// file/path/users-table/columns.tsx
...
import { createColumnFactory } from '../../../shared-ui/table-columns';
const columnFactory = createColumnFactory<Transaction>();
const columns = [~
...
columnFactory.statusByValue('transactionStatus.slug', {
header: 'Status',
}),
columnFactory.date('createdAt', { header: 'Date' }),
...
];
export default columns;This problem is slowing me down so much. Any solution this will be highly appreciated.
Thanks.
dessalines, vkcku and byytelope