name: lsp-custom-requests
description: Serialize URIs correctly across LSP custom requests. Use when defining custom LSP requests/notifications with URI params, sending a URI over Connection.sendRequest, or debugging [object Object] / EntryNotFound / workspace/stat/readFile/readDirectory failures.
LSP Custom Requests — URI Wire Format
Why it breaks
Connection.sendRequest(method, params)runsJSON.stringify(params).vscode-uriUri.toJSON()returnsUriComponents(plain data). See microsoft/vscode-uri src/uri.ts.- Receiver gets a plain object — no prototype, no
toString/fsPath. uri.toString()→"[object Object]"→fs.stat/readFilefails withEntryNotFound.
Rules
- Never call
.toString()/.fsPathon a URI received over the wire without rehydrating first. - Type URI params as
UriComponents(derived); revive on receive.
Pattern — UriComponents + revive
Params type derived from URI.toJSON:
import type { URI } from 'vscode-uri';
type UriComponents = ReturnType<URI['toJSON']>;
type MyParams = { uri: UriComponents };
const params: MyParams = { uri: URI.parse(fileUri) };
connection.sendRequest('my/request', params);
const handler = (params: MyParams) => {
const uri = URI.revive(params.uri);
};
Notes:
vscode-uri's package entry does not re-exportUriComponents; derive viaReturnType<URI['toJSON']>.URI.reviveis the exact inverse oftoJSON— restores_formatted/_fsPathcaches too.
Don't
uri: URIon a wire type and use.toString()/.fsPathon receive — this is the failure mode.- Pass deserialized params straight to
vscode.workspace.fs.*— those APIs expect a realURIinstance.
When uri: URI in params looks fine but isn't
Compiles cleanly (URI on both sides). Runtime receiver sees a plain UriComponents. Check the handler log — uri=[object Object] confirms.