lima-vm/lima · error
field `%s.reverse` must be %t
Error message
field `%s.reverse` must be %t
What it means
Validate() enforces that a port-forwarding rule with `reverse: true` must define a `guestSocket` (validate.go:381-382). A reverse rule forwards a socket from the guest back to the host, so the guest-side endpoint is mandatory; without it the rule is meaningless. The message text `field `%s.reverse` must be %t` is misleading — it really means `reverse: true` requires guestSocket to be set.
Source
Thrown at pkg/limayaml/validate.go:382
}
if rule.GuestSocket == "" && rule.GuestPortRange[1]-rule.GuestPortRange[0] > 0 {
errs = errors.Join(errs, fmt.Errorf("field `%s.hostSocket` can only be mapped from a single port or socket. not a range", field))
}
} else if rule.GuestPortRange[1]-rule.GuestPortRange[0] != rule.HostPortRange[1]-rule.HostPortRange[0] {
errs = errors.Join(errs, fmt.Errorf("field `%s.hostPortRange` must specify the same number of ports as field `%s.guestPortRange`", field, field))
}
if len(rule.HostSocket) >= osutil.UnixPathMax {
errs = errors.Join(errs, fmt.Errorf("field `%s.hostSocket` must be less than UNIX_PATH_MAX=%d characters, but is %d",
field, osutil.UnixPathMax, len(rule.HostSocket)))
}
switch rule.Proto {
case limatype.ProtoTCP, limatype.ProtoUDP, limatype.ProtoAny:
default:
errs = errors.Join(errs, fmt.Errorf("field `%s.proto` must be %#q, %#q, or %#q", field, limatype.ProtoTCP, limatype.ProtoUDP, limatype.ProtoAny))
}
if rule.Reverse && rule.GuestSocket == "" {
errs = errors.Join(errs, fmt.Errorf("field `%s.reverse` must be %t", field, false))
}
if rule.Reverse && rule.HostSocket == "" {
errs = errors.Join(errs, fmt.Errorf("field `%s.reverse` must be %t", field, false))
}
// Not validating that the various GuestPortRanges and HostPortRanges are not overlapping. Rules will be
// processed sequentially and the first matching rule for a guest port determines forwarding behavior.
}
for i, rule := range y.CopyToHost {
field := fmt.Sprintf("CopyToHost[%d]", i)
if rule.GuestFile != "" {
if !path.IsAbs(rule.GuestFile) {
errs = errors.Join(errs, fmt.Errorf("field `%s.guest` must be an absolute path, but is %#q", field, rule.GuestFile))
}
}
if rule.HostFile != "" {
if !filepath.IsAbs(rule.HostFile) {
errs = errors.Join(errs, fmt.Errorf("field `%s.host` must be an absolute path, but is %#q", field, rule.HostFile))
}View on GitHub (pinned to dd909d0973)
Solutions
- Set `guestSocket` to the absolute path of the socket inside the guest for the reverse rule.
- If the rule is not meant to be reversed, remove `reverse: true` (or set it to false).
- For reverse rules, also ensure `hostSocket` is set — the companion check at validate.go:384 enforces that too.
Example fix
# before
portForwards:
- reverse: true
hostSocket: /tmp/agent.sock
# after
portForwards:
- reverse: true
hostSocket: /tmp/agent.sock
guestSocket: /run/agent.sock Defensive patterns
Strategy: validation
Validate before calling
for i, r := range cfg.PortForwards {
if r.Reverse && r.GuestSocket == "" {
return fmt.Errorf("PortForwards[%d]: reverse=true requires guestSocket", i)
}
} Type guard
func validReverseRule(r limatype.PortForward) bool { return !r.Reverse || r.GuestSocket != "" } Try / catch
if err := limayaml.Validate(y, "strict"); err != nil {
return fmt.Errorf("fix portForwards reverse rules (need guestSocket+hostSocket): %w", err)
} Prevention
- Remember reverse rules are socket-to-socket: both guestSocket and hostSocket are required.
- When flipping a rule to reverse, swap both endpoints, not just the flag.
- Keep limayaml.FillDefault + Validate in the pipeline for early feedback.
When it happens
Trigger: Calling limayaml.Validate() (via limactl validate/edit/start/restart/clone/rename or template tools) with PortForwards[i].Reverse == true and GuestSocket == "".
Common situations: User copies a forward rule and flips `reverse: true` but forgets to swap hostSocket/guestSocket endpoints; generating rules programmatically where only HostSocket was populated.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- field `%s.proto` must be %#q, %#q, or %#q
- field `%s.hostPort` must be 0 when field `%s.hostSocket` is
- field `%s.hostPort` must match field `%s.hostPortRange[0]`
- field `%s.guestPortRange[1]` must be greater than or equal t
- field `%s.hostPortRange[1]` must be greater than or equal to
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/46a65daeb2efc7ff.
Report an issue: GitHub.