{"record":{"id":"46a65daeb2efc7ff","repo":"lima-vm/lima","slug":"field-s-reverse-must-be-t","errorCode":null,"errorMessage":"field `%s.reverse` must be %t","messagePattern":"field `(.+?)\\.reverse` must be %t","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/limayaml/validate.go","lineNumber":382,"sourceCode":"\t\t\t}\n\t\t\tif rule.GuestSocket == \"\" && rule.GuestPortRange[1]-rule.GuestPortRange[0] > 0 {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `%s.hostSocket` can only be mapped from a single port or socket. not a range\", field))\n\t\t\t}\n\t\t} else if rule.GuestPortRange[1]-rule.GuestPortRange[0] != rule.HostPortRange[1]-rule.HostPortRange[0] {\n\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `%s.hostPortRange` must specify the same number of ports as field `%s.guestPortRange`\", field, field))\n\t\t}\n\n\t\tif len(rule.HostSocket) >= osutil.UnixPathMax {\n\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `%s.hostSocket` must be less than UNIX_PATH_MAX=%d characters, but is %d\",\n\t\t\t\tfield, osutil.UnixPathMax, len(rule.HostSocket)))\n\t\t}\n\t\tswitch rule.Proto {\n\t\tcase limatype.ProtoTCP, limatype.ProtoUDP, limatype.ProtoAny:\n\t\tdefault:\n\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `%s.proto` must be %#q, %#q, or %#q\", field, limatype.ProtoTCP, limatype.ProtoUDP, limatype.ProtoAny))\n\t\t}\n\t\tif rule.Reverse && rule.GuestSocket == \"\" {\n\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `%s.reverse` must be %t\", field, false))\n\t\t}\n\t\tif rule.Reverse && rule.HostSocket == \"\" {\n\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `%s.reverse` must be %t\", field, false))\n\t\t}\n\t\t// Not validating that the various GuestPortRanges and HostPortRanges are not overlapping. Rules will be\n\t\t// processed sequentially and the first matching rule for a guest port determines forwarding behavior.\n\t}\n\tfor i, rule := range y.CopyToHost {\n\t\tfield := fmt.Sprintf(\"CopyToHost[%d]\", i)\n\t\tif rule.GuestFile != \"\" {\n\t\t\tif !path.IsAbs(rule.GuestFile) {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `%s.guest` must be an absolute path, but is %#q\", field, rule.GuestFile))\n\t\t\t}\n\t\t}\n\t\tif rule.HostFile != \"\" {\n\t\t\tif !filepath.IsAbs(rule.HostFile) {\n\t\t\t\terrs = errors.Join(errs, fmt.Errorf(\"field `%s.host` must be an absolute path, but is %#q\", field, rule.HostFile))\n\t\t\t}","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/limayaml/validate.go#L364-L400","documentation":"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.","triggerScenarios":"Calling limayaml.Validate() (via limactl validate/edit/start/restart/clone/rename or template tools) with PortForwards[i].Reverse == true and GuestSocket == \"\".","commonSituations":"User copies a forward rule and flips `reverse: true` but forgets to swap hostSocket/guestSocket endpoints; generating rules programmatically where only HostSocket was populated.","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."],"exampleFix":"# before\nportForwards:\n  - reverse: true\n    hostSocket: /tmp/agent.sock\n# after\nportForwards:\n  - reverse: true\n    hostSocket: /tmp/agent.sock\n    guestSocket: /run/agent.sock","handlingStrategy":"validation","validationCode":"for i, r := range cfg.PortForwards {\n    if r.Reverse && r.GuestSocket == \"\" {\n        return fmt.Errorf(\"PortForwards[%d]: reverse=true requires guestSocket\", i)\n    }\n}","typeGuard":"func validReverseRule(r limatype.PortForward) bool { return !r.Reverse || r.GuestSocket != \"\" }","tryCatchPattern":"if err := limayaml.Validate(y, \"strict\"); err != nil {\n    return fmt.Errorf(\"fix portForwards reverse rules (need guestSocket+hostSocket): %w\", err)\n}","preventionTips":["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."],"tags":["lima","config-validation","port-forwarding","yaml"],"backgroundTag":"schema-validation-failed","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}