Repository navigation
vscode/lsp type casting bug #5630
Description
Activity
- addedBugSomething isn't workingSomething isn't working
on Jun 7, 2026 I'd like to take this one if it's free — unassigned with no linked PR right now.
Reproducing first, since the report is precise about the trigger: the cast renders inside the column name while the name is still being typed, and it clears on re-render or on reopening the file. That reads like the inlay hints are positioned from a stale document version — the hint keeps an offset computed before the edit, so it lands mid-token once the text has shifted underneath it.
What I plan to check, in order:
- whether the hint response carries the document version it was computed against, and whether that is compared against the current one before the hints are applied
- whether hints are being requested and applied while the document is still changing, rather than being invalidated on edit and recomputed
- whether this is debounce-only, in which case the fix is to drop responses that no longer match the document version rather than to wait longer
I'll come back with what actually causes it before changing anything. If it turns out to be on the server side in
sqlmesh/lsprather than in the extension, I'll say so rather than quietly widening the scope.Reproduced, and the cause is not what I guessed above — posting the correction since I got the mechanism wrong in public.
It is not a document-version problem, a race, or debouncing. All three of the things I said I'd check are dead ends.
sqlmesh/lsp/main.pyregistersdid_openanddid_saveand notextDocument/didChangehandler, so the server's parsed model is frozen until you save.sqlmesh/lsp/hints.py::get_hintsderives every hint'scharacterfrom sqlglot token metadata onlsp_context.context.get_model(...).query— the model parsed from disk when the context was last loaded.VS Code invalidates and re-requests inlay hints on every change, so it is asking correctly; the server answers with offsets from the last saved parse. Version-stamping the responses would not have helped: the server has no correct answer to give at any version, it would just withhold a wrong one.
Direct reproduction — a temp project, edit the buffer, call
get_hints:saved buffer: 1 AS big_boy hint at character 14 edited buffer: 1 AS big_boy_column server still returns character 14 VS Code renders: 1 AS big_boy::INT_columnWhich is the screenshot in the issue.
Two other things worth recording:
- The extension has no inlay-hint code at all — a plain
LanguageClientwith stockvscode-languageclient, no middleware. There is nothing to fix on the TypeScript side, which is where I would have looked first. - A second symptom falls out of the same cause: inserting a line above shifts all the text but not the hints, so they attach to the wrong columns with the wrong types. Not reported, same fix.
PR up shortly. It passes the live document text into
get_hintsand takes positions from parsing that, while still resolving types by name against the loaded model.One thing you may want to weigh in on, since it is a UX call rather than a correctness one: while a column is being renamed it now has no hint until the next save, instead of a hint inside the word. I think that is the better of the two, but the alternative is holding the last good hint and suppressing only the ones that would split a token.
Also, and out of scope here: diagnostics are published from the same reload-on-save context, so they are likely stale between saves in the same way. I have not looked into it.
- The extension has no inlay-hint code at all — a plain
I installed the lsp and the vscode extension (awesome, love them), and it's adding type casting in my select statement. This is great, no complaints on the design philosophy there, but it's getting caught up when I try changing a column name, and even in the middle of when I'm still typing a new column name. It renders the type cast inside of the my column name.
The problem is fixed when I render the model, or close and open the file again, so nothing is getting broken, but it's inconvenient when I'm trying to write a model. Here's an example using the quickstart project. I added a column named 'big_boy_column' and you can see the type cast getting stuck in the middle of that.