{"record":{"id":"479e400a528e06c5","repo":"lima-vm/lima","slug":"field-provision-d-script-must-not-be-empty","errorCode":null,"errorMessage":"field `provision[%d].script` must not be empty","messagePattern":"field `provision\\[(.+?)\\]\\.script` must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/limayaml/validate.go","lineNumber":237,"sourceCode":"\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}\n\t\t\tif p.Overwrite != nil {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].overwrite` can only be set when mode is %#q\", i, limatype.ProvisionModeData))\n\t\t\t}\n\t\t\tif p.Owner != nil {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].owner` can only be set when mode is %#q\", i, limatype.ProvisionModeData))\n\t\t\t}\n\t\t\tif p.Path != nil {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].path` can only be set when mode is %#q, or %#q\", i, limatype.ProvisionModeData, limatype.ProvisionModeYQ))\n\t\t\t}\n\t\t\tif p.Permissions != nil {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].permissions` can only be set when mode is %#q, or %#q\", i, limatype.ProvisionModeData, limatype.ProvisionModeYQ))\n\t\t\t}\n\t\t\tif p.Format != nil {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `provision[%d].format` can only be set when mode is %#q\", i, limatype.ProvisionModeYQ))","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/limayaml/validate.go#L219-L255","documentation":"For provision modes other than data/yq (i.e. system, user, boot, dependency), the entry is a script and `script` must be non-empty. Only `mode: ansible` entries may omit `script` because they supply `playbook` instead. If `script` is missing, null, or an empty string and the mode is not ansible, Validate() rejects the config.","triggerScenarios":"A provision entry like `{mode: user}` with no `script`; an entry whose script was emptied (`script: \"\"`); passed to limactl create/start/restart/edit/apply or template validation.","commonSituations":"Deleting the script body while keeping the entry; YAML indentation mistakes leaving script empty or null; moving a script's content to `content` (data-only field) while leaving mode as default; copying a data-mode entry and changing mode back but forgetting to restore the script.","solutions":["Add the `script` field with the shell commands to run, e.g. `script: |\n  echo hello`","If the entry is meant to write a file, switch to `mode: data` with `path` and `content`","If the entry runs an Ansible playbook, set `mode: ansible` and `playbook: <file>` instead","Remove the empty provision entry if it is no longer needed"],"exampleFix":"# before\nprovision:\n  - mode: user\n# after\nprovision:\n  - mode: user\n    script: |\n      #!/bin/bash\n      echo hello > /home/user/hello.txt","handlingStrategy":"validation","validationCode":"// Go: every non-ansible provision entry needs a script\nfor i, p := range cfg.Provision {\n    mode := limatype.ProvisionModeSystem\n    if p.Mode != nil { mode = *p.Mode }\n    isAnsible := mode == limatype.ProvisionModeAnsible\n    if !isAnsible && (p.Script == nil || *p.Script == \"\") {\n        return fmt.Errorf(\"provision[%d]: script required for mode %q\", i, mode)\n    }\n}","typeGuard":"func provisionHasScript(p limatype.Provision) bool {\n    return (p.Script != nil && *p.Script != \"\") || (p.Mode != nil && *p.Mode == limatype.ProvisionModeAnsible)\n}","tryCatchPattern":null,"preventionTips":["Never delete a script body without deleting its whole provision entry","Check YAML indentation — a misindented script becomes null silently","Use `mode: data` for file content rather than leaving script empty","Validate templates with `limactl validate` after every edit"],"tags":["lima","config-validation","provision","script"],"backgroundTag":"missing-required-argument","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}