lima-vm/lima · error
field `user.shell` must be one of %v for Windows guest, got
Error message
field `user.shell` must be one of %v for Windows guest, got %#q
What it means
When `os: windows`, the optional `user.shell` must be one of the shells Lima supports on Windows guests (SupportedWindowsShells, e.g. cmd/powershell-style entries) rather than an arbitrary absolute path. Validate() rejects any other value.
Source
Thrown at pkg/limayaml/validate.go:71
case limatype.WINDOWS:
if *y.VMType != limatype.QEMU {
errs = errors.Join(errs, fmt.Errorf("currently Windows guest is only supported on %#q; got %#q", limatype.QEMU, *y.VMType))
}
if !slices.Contains([]limatype.Arch{limatype.X8664, limatype.AARCH64}, *y.Arch) {
errs = errors.Join(errs, fmt.Errorf("currently Windows guest is only supported on [%#q, %#q]; got %#q", limatype.X8664, limatype.AARCH64, *y.Arch))
}
default:
errs = errors.Join(errs, fmt.Errorf("field `os` must be one of %#q; got %#q", limatype.OSTypes, *y.OS))
}
if !slices.Contains(limatype.ArchTypes, *y.Arch) {
errs = errors.Join(errs, fmt.Errorf("field `arch` must be one of %v; got %#q", limatype.ArchTypes, *y.Arch))
}
if y.User.Shell != nil {
shell := *y.User.Shell
if *y.OS == limatype.WINDOWS {
if !IsSupportedWindowsShell(shell) {
errs = errors.Join(errs, fmt.Errorf("field `user.shell` must be one of %v for Windows guest, got %#q", SupportedWindowsShells, shell))
}
} else if !path.IsAbs(shell) {
errs = errors.Join(errs, fmt.Errorf("field `user.shell` must be an absolute path, got %#q", shell))
}
}
if len(y.Images) == 0 {
errs = errors.Join(errs, errors.New("field `images` must be set"))
}
for i, f := range y.Images {
err := validateFileObject(f.File, fmt.Sprintf("images[%d]", i))
if err != nil {
errs = errors.Join(errs, err)
}
if f.Kernel != nil {
err := validateFileObject(f.Kernel.File, fmt.Sprintf("images[%d].kernel", i))
if err != nil {
errs = errors.Join(errs, err)View on GitHub (pinned to dd909d0973)
Solutions
- Set `user.shell` to one of the listed SupportedWindowsShells values
- Remove the `user.shell` line so the guest default shell is used
- Switch `os` back to linux/darwin/freebsd if a POSIX shell was intended
Example fix
// before os: windows user: shell: /bin/bash // after os: windows user: shell: powershell.exe
Defensive patterns
Strategy: validation
Validate before calling
func validShellForOS(os, shell string) bool {
if os != "windows" {
return shell == "" || path.IsAbs(shell)
}
return shell == "" || limayaml.IsSupportedWindowsShell(shell)
} Type guard
func isSupportedWindowsShell(s string) bool {
return slices.Contains(limayaml.SupportedWindowsShells, s)
} Try / catch
if err := limayaml.Validate(y, false); err != nil {
if strings.Contains(err.Error(), "user.shell must be one of") {
return fmt.Errorf("unsupported Windows shell: %w", err)
}
return err
} Prevention
- Only set user.shell on Windows templates with values from SupportedWindowsShells
- Omit user.shell to accept the guest default
- Re-check shell settings when switching a template between linux and windows
When it happens
Trigger: Template sets `os: windows` and `user.shell` to a POSIX path like /bin/bash or a shell not in SupportedWindowsShells.
Common situations: Reusing a Linux template's shell setting after switching the guest to Windows; assuming the absolute-path rule applies on Windows too.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- currently Windows guest is only supported on [%#q, %#q]; got
- currently Windows guest OS is only supported on QEMU
- currently Windows guest OS is only supported on QEMU
- field `os` must be one of %#q; got %#q
- field `arch` must be one of %v; got %#q
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/9886be3b0c5a0bda.
Report an issue: GitHub.