lima-vm/lima · error

field `provision[%d].path` must not be empty when mode is %#

Error message

field `provision[%d].path` must not be empty when mode is %#q

What it means

In `limayaml.Validate`, provision entries with mode `data` or `yq` must declare the guest file they operate on via the `path` field. A nil `path` is rejected explicitly (with an early return) because later validation and the CIDATA generation would dereference it and panic, and there is no meaningful default target file for these modes.

Source

Thrown at pkg/limayaml/validate.go:219

		case limatype.ProvisionModeSystem, limatype.ProvisionModeUser, limatype.ProvisionModeBoot, limatype.ProvisionModeData, limatype.ProvisionModeDependency, limatype.ProvisionModeAnsible, limatype.ProvisionModeYQ:
		default:
			errs = errors.Join(errs, fmt.Errorf("field `provision[%d].mode` must one of %#q, %#q, %#q, %#q, %#q, %#q, or %#q",
				i, limatype.ProvisionModeSystem, limatype.ProvisionModeUser, limatype.ProvisionModeBoot, limatype.ProvisionModeData, limatype.ProvisionModeDependency, limatype.ProvisionModeAnsible, limatype.ProvisionModeYQ))
		}
		if p.Mode != limatype.ProvisionModeDependency && p.SkipDefaultDependencyResolution != nil {
			errs = errors.Join(errs, fmt.Errorf("field `provision[%d].mode` cannot set skipDefaultDependencyResolution, only valid on scripts of type %#q",
				i, limatype.ProvisionModeDependency))
		}

		if *y.OS == limatype.WINDOWS && (p.Mode == limatype.ProvisionModeAnsible || p.Mode == limatype.ProvisionModeBoot || p.Mode == limatype.ProvisionModeYQ) {
			errs = errors.Join(errs, fmt.Errorf("provision mode %#q is not supported on Windows VM", p.Mode))
		}

		// This can lead to fatal Panic if p.Path is nil, better to return an error here
		switch p.Mode {
		case limatype.ProvisionModeData, limatype.ProvisionModeYQ:
			if p.Path == nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].path` must not be empty when mode is %#q", i, p.Mode))
				return errs
			}
			if !path.IsAbs(*p.Path) {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].path` must be an absolute path", i))
			}
			if p.Mode == limatype.ProvisionModeData && p.Content == nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].content` must not be empty when mode is %#q", i, p.Mode))
			}
			if p.Mode == limatype.ProvisionModeYQ && p.Expression == nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].expression` must not be empty when mode is %#q", i, p.Mode))
			}
			// FillDefaults makes sure that p.Permissions is not nil
			if _, err := strconv.ParseInt(*p.Permissions, 8, 64); err != nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].permissions` must be an octal number: %w", i, err))
			}
		default:
			if (p.Script == nil || *p.Script == "") && p.Mode != limatype.ProvisionModeAnsible {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].script` must not be empty", i))

View on GitHub (pinned to dd909d0973)

Solutions

  1. Add a `path` key with the absolute guest file path to the data/yq provision entry.
  2. If the entry was meant to run a script, switch the mode to "user"/"system" and use `script` instead of path/content.
  3. Re-validate with limactl template validate before starting the instance.

Example fix

# before
provision:
  - mode: data
    content: "hello"
# after
provision:
  - mode: data
    path: /etc/hello.conf
    content: "hello"
Defensive patterns

Strategy: validation

Validate before calling

for i, p := range cfg.Provision {
	if (p.Mode == "data" || p.Mode == "yq") && p.Path == nil {
		return fmt.Errorf("provision[%d]: mode %q requires a path", i, p.Mode)
	}
}

Type guard

func provisionNeedsPath(p limatype.Provision) bool {
	return p.Mode == limatype.ProvisionModeData || p.Mode == limatype.ProvisionModeYQ
}

Try / catch

if err := limayaml.Validate(y, false, "config.yaml"); err != nil {
	if strings.Contains(err.Error(), "`provision[") && strings.Contains(err.Error(), "must not be empty when mode is") {
		return fmt.Errorf("fix the data/yq provision entry (add path): %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Any Validate-calling command (create/start/edit/restart/apply/clone/rename/template validate/template args) on a YAML containing `provision: - mode: data` (or `mode: yq`) without a `path:` key.

Common situations: Writing a data-mode file entry and omitting path because script-mode entries don't need one; a partial merge/anchor that drops the path key; hand-editing a template and deleting the path line while keeping content or expression.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01). Data as JSON: /api/errors/7ededa6cfda6b252. Report an issue: GitHub.