charmbracelet/crush · critical
failed to create lsp client: %w
Error message
failed to create lsp client: %w
What it means
Once command, args, and env are resolved, createPowernapClient builds a powernap.ClientConfig and calls powernap.NewClient. If that constructor fails, the error is wrapped as "failed to create lsp client". This typically means the underlying client could not be constructed (e.g. invalid combination of transport/command options) and the LSP server process was never started.
Source
Thrown at internal/lsp/client.go:223
clientConfig := powernap.ClientConfig{
Command: home.Long(command),
Args: args,
RootURI: rootURI,
Environment: envs,
Settings: c.config.Options,
InitOptions: c.config.InitOptions,
WorkspaceFolders: []protocol.WorkspaceFolder{
{
URI: rootURI,
Name: filepath.Base(c.cwd),
},
},
}
powernapClient, err := powernap.NewClient(clientConfig)
if err != nil {
return fmt.Errorf("failed to create lsp client: %w", err)
}
c.client = powernapClient
return nil
}
// registerHandlers registers the standard LSP notification and request handlers.
func (c *Client) registerHandlers() {
c.RegisterServerRequestHandler("workspace/applyEdit", HandleApplyEdit(c.client.GetOffsetEncoding()))
c.RegisterServerRequestHandler("workspace/configuration", HandleWorkspaceConfiguration)
c.RegisterServerRequestHandler("client/registerCapability", HandleRegisterCapability)
c.RegisterServerRequestHandler("window/workDoneProgress/create", HandleWorkDoneProgressCreate)
c.RegisterNotificationHandler("window/showMessage", func(ctx context.Context, method string, params json.RawMessage) {
if c.debug {
HandleServerMessage(ctx, method, params)
}
})
c.RegisterNotificationHandler("textDocument/publishDiagnostics", func(_ context.Context, _ string, params json.RawMessage) {View on GitHub (pinned to 7944b8e522)
Solutions
- Verify the resolved LSP command exists and is executable: `which <command>` / `command -v <command>`.
- Install the LSP server or add its directory to PATH in the environment crush runs in.
- Check file permissions on the server binary (chmod +x).
- Run the command manually with the resolved args to confirm it can start.
- Confirm powernap client config fields (Command, Args, RootURI) are valid for the transport.
Example fix
// before command = "gopls" // not installed // after // go install golang.org/x/tools/gopls@latest command = "gopls"
Defensive patterns
Strategy: try-catch
Validate before calling
cmd, _ := resolver.ResolveValue(lspCfg.Command)
if _, err := exec.LookPath(cmd); err != nil {
return fmt.Errorf("lsp server %q is not installed or not executable", cmd)
} Type guard
func serverBinaryAvailable(cfg LSPConfig, r Resolver) bool {
cmd, err := r.ResolveValue(cfg.Command)
if err != nil {
return false
}
_, err = exec.LookPath(cmd)
return err == nil
} Try / catch
client, err := lsp.New(cfg)
if err != nil {
if strings.Contains(err.Error(), "failed to create lsp client") {
slog.Error("Could not start LSP server; check it is installed and on PATH", "error", err)
return nil // degrade gracefully; LSP features disabled
}
return err
} Prevention
- Document required LSP binaries and install them in provisioning scripts/containers.
- Check binary availability at startup and warn instead of hard-failing.
- Pin server versions to avoid surprises after upstream releases.
When it happens
Trigger: Calling New or Restart where powernap.NewClient(clientConfig) returns an error — e.g. the resolved command is not an executable binary on PATH, or the client config is structurally invalid for the transport.
Common situations: LSP server binary not installed or not on PATH in the runtime environment (works locally, fails in CI/container); command lacks execute permission; incompatible powernap client options after a version change.
Related errors
- error starting shell: %w
- failed to search for symbol: %w
- symbol '%s' not found in grep results
- no LSP client handles any file matching '%s'
- permission request failed: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/3e818488ee8942a1.
Report an issue: GitHub.