{"record":{"id":"35de8e4130c14c08","repo":"lima-vm/lima","slug":"field-user-shell-must-be-an-absolute-path-got","errorCode":null,"errorMessage":"field `user.shell` must be an absolute path, got %#q","messagePattern":"field `user\\.shell` must be an absolute path, got %#q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/limayaml/validate.go","lineNumber":74,"sourceCode":"\t\t}\n\t\tif !slices.Contains([]limatype.Arch{limatype.X8664, limatype.AARCH64}, *y.Arch) {\n\t\t\terrs = errors.Join(errs, fmt.Errorf(\"currently Windows guest is only supported on [%#q, %#q]; got %#q\", limatype.X8664, limatype.AARCH64, *y.Arch))\n\t\t}\n\tdefault:\n\t\terrs = errors.Join(errs, fmt.Errorf(\"field `os` must be one of %#q; got %#q\", limatype.OSTypes, *y.OS))\n\t}\n\tif !slices.Contains(limatype.ArchTypes, *y.Arch) {\n\t\terrs = errors.Join(errs, fmt.Errorf(\"field `arch` must be one of %v; got %#q\", limatype.ArchTypes, *y.Arch))\n\t}\n\n\tif y.User.Shell != nil {\n\t\tshell := *y.User.Shell\n\t\tif *y.OS == limatype.WINDOWS {\n\t\t\tif !IsSupportedWindowsShell(shell) {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `user.shell` must be one of %v for Windows guest, got %#q\", SupportedWindowsShells, shell))\n\t\t\t}\n\t\t} else if !path.IsAbs(shell) {\n\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `user.shell` must be an absolute path, got %#q\", shell))\n\t\t}\n\t}\n\n\tif len(y.Images) == 0 {\n\t\terrs = errors.Join(errs, errors.New(\"field `images` must be set\"))\n\t}\n\tfor i, f := range y.Images {\n\t\terr := validateFileObject(f.File, fmt.Sprintf(\"images[%d]\", i))\n\t\tif err != nil {\n\t\t\terrs = errors.Join(errs, err)\n\t\t}\n\t\tif f.Kernel != nil {\n\t\t\terr := validateFileObject(f.Kernel.File, fmt.Sprintf(\"images[%d].kernel\", i))\n\t\t\tif err != nil {\n\t\t\t\terrs = errors.Join(errs, err)\n\t\t\t}\n\t\t\tif f.Kernel.Arch != f.Arch {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"images[%d].kernel has unexpected architecture %#q, must be %#q\", i, f.Kernel.Arch, f.Arch))","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/limayaml/validate.go#L56-L92","documentation":"For non-Windows guests (linux, darwin, freebsd), the optional `user.shell` must be an absolute path (e.g. /bin/bash). Relative paths like `bash` fail validation because Lima passes the shell path to the guest directly. Checked in Validate().","triggerScenarios":"`user.shell` set to a bare command name (\"bash\", \"zsh\") or a relative path (\"./bin/sh\") while os is not windows.","commonSituations":"Users accustomed to $SHELL names write `shell: zsh`; templates copied from dotfiles configs.","solutions":["Use the full absolute guest path, e.g. /bin/zsh or /usr/bin/fish","Remove `user.shell` to use the guest default","Verify the shell binary exists at that path in the guest image"],"exampleFix":"// before\nuser:\n  shell: zsh\n// after\nuser:\n  shell: /bin/zsh","handlingStrategy":"validation","validationCode":"func validShellPath(os, shell string) bool {\n\treturn os == \"windows\" || shell == \"\" || path.IsAbs(shell)\n}","typeGuard":null,"tryCatchPattern":"if err := limayaml.Validate(y, false); err != nil {\n\tif strings.Contains(err.Error(), \"must be an absolute path\") {\n\t\treturn fmt.Errorf(\"shell must be absolute: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Always write the full guest path like /bin/bash, never a bare command name","Resolve the binary with `command -v zsh` inside a similar guest to find the path","Prefer omitting user.shell unless a non-default shell is required"],"tags":["lima","shell","path-validation"],"backgroundTag":"absolute-path-required","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}