Skip to content

textDocument/inlayHint returns no results despite inlayHintProvider: true in capabilities #2771

@dumidusw

Description

@dumidusw

Describe the bug

The Svelte Language Server advertises inlayHintProvider: true during initialization, but it does not return any inlay hints when textDocument/inlayHint is called, even with a valid .svelte file containing annotated TypeScript.

Reproduction

After many failed attempts with Neovim's Mason installed svelte language server and nvim-lspconfig
I tried this
Cloned and built the language server from source.
Launched the server directly:
pnpm exec node ./bin/server.js --stdio
Then I ran a Node.js test script to simulate LSP client behavior.
Sent the following messages in order:
initialize
initialized
textDocument/didOpen (with .svelte file)
textDocument/inlayHint (for a valid range)
Here is the test script I used (includes request logic and expected behaviors):

Click to expand full script // test-lsp.cjs const { spawn } = require('child_process'); const path = require('path'); const fs = require('fs');

const svelteLS = spawn(
'node',
[path.resolve(__dirname, './bin/server.js'), '--stdio'],
{ cwd: process.cwd() }
);

const pending = new Map();
let buffer = '';

svelteLS.stdout.on('data', (data) => {
buffer += data.toString();

while (buffer.includes('\r\n\r\n')) {
const headerEnd = buffer.indexOf('\r\n\r\n');
const match = buffer.slice(0, headerEnd).match(/Content-Length: (\d+)/i);
if (!match) break;

const length = parseInt(match[1], 10);
const totalLength = headerEnd + 4 + length;
if (buffer.length < totalLength) break;

const jsonStr = buffer.slice(headerEnd + 4, totalLength);
buffer = buffer.slice(totalLength);

const msg = JSON.parse(jsonStr);
if (msg.id && pending.has(msg.id)) {
  pending.get(msg.id)(msg);
  pending.delete(msg.id);
} else {
  console.log('Server notification:', msg);
}

}
});

svelteLS.stderr.on('data', (data) => {
console.error('Server Error:', data.toString());
});

function sendLSP(msg) {
const json = JSON.stringify(msg);
const header = Content-Length: ${Buffer.byteLength(json)}\r\n\r\n;
svelteLS.stdin.write(header + json);
}

function sendRequest(id, method, params) {
return new Promise((resolve) => {
pending.set(id, resolve);
sendLSP({ jsonrpc: '2.0', id, method, params });
});
}

function sendNotification(method, params) {
sendLSP({ jsonrpc: '2.0', method, params });
}

function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

(async () => {
const rootUri = file://${process.cwd()};

try {
const initResult = await sendRequest(1, 'initialize', {
rootUri,
capabilities: {},
});
console.log('Initialized:', initResult);

sendNotification('initialized', {});

sendNotification('textDocument/didOpen', {
  textDocument: {
    uri: `${rootUri}/test.svelte`,
    languageId: 'svelte',
    version: 1,
    text: fs.readFileSync('test.svelte', 'utf-8'),
  },
});

await delay(2000);

const result = await sendRequest(2, 'textDocument/inlayHint', {
  textDocument: { uri: `${rootUri}/test.svelte` },
  range: {
    start: { line: 0, character: 0 },
    end: { line: 20, character: 0 },
  },
});

if (result.result?.length) {
  console.log('Inlay hints received:', JSON.stringify(result.result, null, 2));
} else {
  console.log('No inlay hints received.');
}

} catch (err) {
console.error('Error during LSP communication:', err);
} finally {
svelteLS.kill();
}
})();

Test File (test.svelte) <script lang="ts"> let count: number = 0; const message: string = 'Hello';

function add(a: number, b: number): number {
return a + b;
}
</script>

<button on:click={() => count++}>
{count}
{message}

This is the output I got
The server successfully initializes and syncs the file.
Logs show it attempts to load configs and snapshots.
But textDocument/inlayHint returns no results, and no errors are thrown.

Expected behaviour

When sending a textDocument/inlayHint request for a .svelte file containing TypeScript code with type annotations, I want the language server to return an array of inlay hints, such as parameter names, variable type annotations, or other relevant hints, according to the TypeScript language service's usual behavior.

This means that any annotated or inferable types in the script section should produce inlay hints that a compatible client (e.g., Neovim with inlay hints enabled) can display.

System Info

Linux Mint
NeoVim 0.11.1

Which package is the issue about?

svelte-language-server

Additional Information, eg. Screenshots

This leads me to believe that the Svelte LS currently does not implement or forward inlay hints from the TypeScript plugin layer, even though it advertises support.

Is this feature just not implemented yet?

Or is there a configuration or project setup I'm missing?
Many thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions