lima-vm/lima · error

field `provision[%d].format` can only be set when mode is %#

Error message

field `provision[%d].format` can only be set when mode is %#q

What it means

`format` specifies the input format (e.g. yaml/json) of the target for a yq-mode provision entry, so it is only valid when `mode` is "yq". Validate() rejects `format` on every other mode. The rendered message names `"yq"` as the allowed mode.

Source

Thrown at pkg/limayaml/validate.go:255

				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].script` must not be empty", i))
			}
			if p.Content != nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].content` can only be set when mode is %#q", i, limatype.ProvisionModeData))
			}
			if p.Overwrite != nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].overwrite` can only be set when mode is %#q", i, limatype.ProvisionModeData))
			}
			if p.Owner != nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].owner` can only be set when mode is %#q", i, limatype.ProvisionModeData))
			}
			if p.Path != nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].path` can only be set when mode is %#q, or %#q", i, limatype.ProvisionModeData, limatype.ProvisionModeYQ))
			}
			if p.Permissions != nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].permissions` can only be set when mode is %#q, or %#q", i, limatype.ProvisionModeData, limatype.ProvisionModeYQ))
			}
			if p.Format != nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].format` can only be set when mode is %#q", i, limatype.ProvisionModeYQ))
			}
		}
		if p.Playbook != "" {
			if p.Mode != limatype.ProvisionModeAnsible {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].playbook can only be set when mode is %#q", i, limatype.ProvisionModeAnsible))
			}
			if p.Script != nil && *p.Script != "" {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].script must be empty if playbook is set", i))
			}
			playbook := p.Playbook
			if _, err := os.Stat(playbook); err != nil {
				errs = errors.Join(errs, fmt.Errorf("field `provision[%d].playbook` refers to an inaccessible path: %#q: %w", i, playbook, err))
			}
			logrus.Warnf("provision mode %#q is deprecated, use `ansible-playbook %#q` instead", limatype.ProvisionModeAnsible, playbook)
		}
		if p.Script != nil {
			if strings.Contains(*p.Script, "LIMA_CIDATA") {
				logrus.Warn("provisioning scripts should not reference the LIMA_CIDATA variables")

View on GitHub (pinned to dd909d0973)

Solutions

  1. Set `mode: yq` (with `path` and `expression`) if the entry edits YAML/JSON with yq
  2. Delete the `format` field from the non-yq entry
  3. data mode has no format option; just provide plain `content`

Example fix

# before
provision:
  - mode: data
    path: /etc/foo.yaml
    format: yaml
    content: a: b
# after
provision:
  - mode: data
    path: /etc/foo.yaml
    content: |
      a: b
Defensive patterns

Strategy: validation

Validate before calling

// Go: format requires yq mode
for i, p := range cfg.Provision {
    mode := limatype.ProvisionModeSystem
    if p.Mode != nil { mode = *p.Mode }
    if p.Format != nil && mode != limatype.ProvisionModeYQ {
        return fmt.Errorf("provision[%d]: format requires mode yq", i)
    }
}

Type guard

func formatAllowed(p limatype.Provision) bool {
    return p.Format == nil || (p.Mode != nil && *p.Mode == limatype.ProvisionModeYQ)
}

Prevention

When it happens

Trigger: A provision entry with mode system/user/boot/dependency/ansible/data (or unset) that sets `format`, during create/start/restart/edit/apply/template validation.

Common situations: Leaving `format` behind after changing an entry from yq mode to data mode; template tools emitting format for all entries; misunderstanding that format relates to data-mode content encoding.

Related errors


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