{"record":{"id":"0fade399bd05855c","repo":"lima-vm/lima","slug":"field-provision-d-path-must-be-an-absolute-pat","errorCode":null,"errorMessage":"field `provision[%d].path` must be an absolute path","messagePattern":"field `provision\\[(.+?)\\]\\.path` must be an absolute path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/limayaml/validate.go","lineNumber":223,"sourceCode":"\t\t}\n\t\tif p.Mode != limatype.ProvisionModeDependency && p.SkipDefaultDependencyResolution != nil {\n\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].mode` cannot set skipDefaultDependencyResolution, only valid on scripts of type %#q\",\n\t\t\t\ti, limatype.ProvisionModeDependency))\n\t\t}\n\n\t\tif *y.OS == limatype.WINDOWS && (p.Mode == limatype.ProvisionModeAnsible || p.Mode == limatype.ProvisionModeBoot || p.Mode == limatype.ProvisionModeYQ) {\n\t\t\terrs = errors.Join(errs, fmt.Errorf(\"provision mode %#q is not supported on Windows VM\", p.Mode))\n\t\t}\n\n\t\t// This can lead to fatal Panic if p.Path is nil, better to return an error here\n\t\tswitch p.Mode {\n\t\tcase limatype.ProvisionModeData, limatype.ProvisionModeYQ:\n\t\t\tif p.Path == nil {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].path` must not be empty when mode is %#q\", i, p.Mode))\n\t\t\t\treturn errs\n\t\t\t}\n\t\t\tif !path.IsAbs(*p.Path) {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].path` must be an absolute path\", i))\n\t\t\t}\n\t\t\tif p.Mode == limatype.ProvisionModeData && p.Content == nil {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].content` must not be empty when mode is %#q\", i, p.Mode))\n\t\t\t}\n\t\t\tif p.Mode == limatype.ProvisionModeYQ && p.Expression == nil {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].expression` must not be empty when mode is %#q\", i, p.Mode))\n\t\t\t}\n\t\t\t// FillDefaults makes sure that p.Permissions is not nil\n\t\t\tif _, err := strconv.ParseInt(*p.Permissions, 8, 64); err != nil {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].permissions` must be an octal number: %w\", i, err))\n\t\t\t}\n\t\tdefault:\n\t\t\tif (p.Script == nil || *p.Script == \"\") && p.Mode != limatype.ProvisionModeAnsible {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].script` must not be empty\", i))\n\t\t\t}\n\t\t\tif p.Content != nil {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].content` can only be set when mode is %#q\", i, limatype.ProvisionModeData))\n\t\t\t}","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/limayaml/validate.go#L205-L241","documentation":"For provision modes `data` and `yq`, Lima writes/edits a file at a fixed location inside the guest, so `path` must be an absolute POSIX path. `limayaml.Validate` checks `path.IsAbs(*p.Path)` and fails when a relative path is given, because a relative path has no defined base directory inside the guest filesystem.","triggerScenarios":"Running any Validate-calling limactl command on a YAML where a provision entry with mode \"data\" or \"yq\" has a `path` like `etc/foo.conf`, `./foo.conf`, or a Windows-style/empty path that `path.IsAbs` rejects.","commonSituations":"Authoring the path relative to the project or template directory by habit; copying a host-relative path into the guest entry; tilde-prefixed paths (`~/x`) which are not absolute per path.IsAbs; typos that leave a leading slash off.","solutions":["Prefix the path with `/` and give the full guest-absolute location (e.g. /etc/motd.d/lima).","Replace a `~/...` path with the explicit absolute home path if the guest user is known, or use a script-mode provision to write to $HOME.","Re-run validation to confirm the path now passes."],"exampleFix":"# before\n- mode: data\n  path: etc/sysctl.d/99-lima.conf\n  content: \"vm.swappiness=10\"\n# after\n- mode: data\n  path: /etc/sysctl.d/99-lima.conf\n  content: \"vm.swappiness=10\"","handlingStrategy":"validation","validationCode":"for i, p := range cfg.Provision {\n\tif p.Mode == \"data\" || p.Mode == \"yq\" {\n\t\tif p.Path != nil && !strings.HasPrefix(*p.Path, \"/\") {\n\t\t\treturn fmt.Errorf(\"provision[%d]: path %q must be absolute\", i, *p.Path)\n\t\t}\n\t}\n}","typeGuard":"func isGuestAbsPath(p *string) bool {\n\treturn p != nil && path.IsAbs(*p)\n}","tryCatchPattern":"if err := limayaml.Validate(y, false, \"config.yaml\"); err != nil {\n\tif strings.Contains(err.Error(), \"must be an absolute path\") {\n\t\treturn fmt.Errorf(\"rewrite provision path as a guest-absolute path: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Write guest file paths starting with `/`; never reuse host-relative paths.","Remember `~` is not absolute for path.IsAbs; use an explicit /home/user/... path or a script.","Add a template lint rule that enforces absolute paths for data/yq provision entries."],"tags":["lima","limayaml","validation","path","provision"],"backgroundTag":"path-must-be-absolute","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}