GoogleContainerTools/skaffold · error
expected WorkspaceFolders to have at least one value, got 0
Error message
expected WorkspaceFolders to have at least one value, got 0
What it means
Skaffold's LSP server, on receiving the LSP 'initialize' request, requires params.WorkspaceFolders to contain at least one workspace because it chdirs into the first folder and supports only one workspace per session. When the client sends an initialize request with zero workspace folders, this error is returned.
Source
Thrown at pkg/skaffold/lsp/handler.go:117
defer func() {
err := recover()
if err != nil {
log.Entry(ctx).Errorf("recovered from panic at %s: %v\n", req.Method(), err)
log.Entry(ctx).Errorf("stacktrace from panic: \n%s", string(debug.Stack()))
}
}()
log.Entry(ctx).Debugf("req.Method(): %q\n", req.Method())
switch req.Method() {
case protocol.MethodInitialize:
var params protocol.InitializeParams
json.Unmarshal(req.Params(), ¶ms)
log.Entry(ctx).Debugf("InitializeParams: %+v\n", params)
log.Entry(ctx).Debugf("InitializeParams.Capabilities.TextDocument: %+v\n", params.Capabilities.TextDocument)
// TODO(aaron-prindle) currently this only supports workspaces of length one (or the first of the list of workspaces)
// This used to be a single workspace field/value before lsp spec changes and I only know how to open one workspace per
// session in VSCode atm so this should be ok initially
if len(params.WorkspaceFolders) == 0 {
return fmt.Errorf("expected WorkspaceFolders to have at least one value, got 0")
}
// TODO(aaron-prindle) does workspace changing send a new 'initialize' or is there workspaceChange msg? Need to make sure that is handled...
// and we don't keep initialize workspace always
err := os.Chdir(uriToFilename(uri.URI(params.WorkspaceFolders[0].URI)))
if err != nil {
return err
}
// TODO(aaron-prindle) might need some checks to verify the initialize requests supports these,
// right now assuming VS Code w/ supported methods - seems like an ok assumption for now
if err := reply(ctx, protocol.InitializeResult{
Capabilities: protocol.ServerCapabilities{
TextDocumentSync: protocol.TextDocumentSyncOptions{
Change: protocol.TextDocumentSyncKindFull,
OpenClose: true,
Save: &protocol.SaveOptions{
IncludeText: true,
},
},View on GitHub (pinned to a1189de023)
Solutions
- Send the workspace root in InitializeParams.WorkspaceFolders (name + URI) when initializing the client
- If the client only supports rootUri/rootPath, upgrade it or convert rootUri into a single WorkspaceFolders entry in your adapter
- For tests, construct params with WorkspaceFolders: []WorkspaceFolder{{URI: "file:///path/to/workspace"}}
Example fix
// before: client sends
params := InitializeParams{} // no WorkspaceFolders
// after
params := InitializeParams{
WorkspaceFolders: []WorkspaceFolder{{
Name: "my-project",
URI: "file:///home/dev/my-project",
}},
} Defensive patterns
Strategy: validation
Validate before calling
// client side, before sending initialize
if len(params.WorkspaceFolders) == 0 && params.RootURI != "" {
params.WorkspaceFolders = []WorkspaceFolder{{Name: filepath.Base(params.RootURI), URI: params.RootURI}}
}
if len(params.WorkspaceFolders) == 0 {
return errors.New("cannot initialize skaffold LSP without a workspace folder")
} Type guard
func hasWorkspaceFolders(p InitializeParams) bool { return len(p.WorkspaceFolders) > 0 } Try / catch
err := initializeHandler(ctx, conn, params)
if err != nil && strings.Contains(err.Error(), "expected WorkspaceFolders") {
return jsonrpc2.NewError(codeInvalidParams, "initialize requires at least one workspaceFolder")
} Prevention
- Always populate WorkspaceFolders in InitializeParams when writing LSP clients/tests
- Convert legacy rootUri/rootPath into a single WorkspaceFolders entry
- Do not open single files without a workspace against this server
- Handle the invalid-params JSON-RPC error gracefully on the client to prompt for a folder
When it happens
Trigger: An LSP client (or hand-rolled LSP test client) sends an Initialize request with WorkspaceFolders empty or omitted; older clients that predate workspace-folders support send only rootUri/rootPath (or neither).
Common situations: Testing the LSP server with a minimal client that forgets WorkspaceFolders; an editor integration opening a single file with no workspace; protocol version mismatches where folders were sent in the legacy rootUri field.
Related errors
- creating runner: %w
- getting relative path of %s
- determining build workspace directory for image %v: %w
- image %q context %q does not exist
- failed to initialize sync state for %q: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/aee1a9690cce4326.
Report an issue: GitHub.