lima-vm/lima · critical
c.Paths.SocketVMNet is empty
Error message
c.Paths.SocketVMNet is empty
What it means
Within StartCmd's SocketVMNet branch, the code re-checks that c.Paths.SocketVMNet is non-empty before formatting the command, panicking with 'c.Paths.SocketVMNet is empty' if it is. This is a defense-in-depth assertion: normally IsDaemonInstalled would have panicked earlier, so reaching here implies an inconsistent config state (e.g. IsDaemonInstalled behavior changed or config mutated between calls).
Source
Thrown at pkg/networks/commands.go:107
return osutil.LookupUser("root")
}
return osutil.User{}, fmt.Errorf("daemon %#q not defined", daemon)
}
func (c *Config) MkdirCmd() string {
return fmt.Sprintf("/bin/mkdir -m 775 -p %s", c.Paths.VarRun)
}
func (c *Config) StartCmd(name, daemon string) string {
if ok, _ := c.IsDaemonInstalled(daemon); !ok {
panic(fmt.Errorf("daemon %#q is not available", daemon))
}
var cmd string
switch daemon {
case SocketVMNet:
nw := c.Networks[name]
if c.Paths.SocketVMNet == "" {
panic("c.Paths.SocketVMNet is empty")
}
cmd = fmt.Sprintf("%s --pidfile=%s --socket-group=%s --vmnet-mode=%s",
c.Paths.SocketVMNet, c.PIDFile(name, SocketVMNet), c.Group, nw.Mode)
switch nw.Mode {
case ModeBridged:
cmd += fmt.Sprintf(" --vmnet-interface=%s", nw.Interface)
case ModeHost, ModeShared:
cmd += fmt.Sprintf(" --vmnet-gateway=%s --vmnet-dhcp-end=%s --vmnet-mask=%s",
nw.Gateway, nw.DHCPEnd, nw.NetMask)
}
cmd += " " + c.Sock(name)
default:
panic(fmt.Errorf("unexpected daemon %#q", daemon))
}
return cmd
}
func (c *Config) StopCmd(name, daemon string) string {View on GitHub (pinned to dd909d0973)
Solutions
- Ensure Paths.SocketVMNet is populated from networks.yaml before building a Config programmatically
- Do not mutate Config fields after validation; treat Config as read-only
- Construct the config via the normal loader so paths are validated once
Example fix
// before
cfg := &networks.Config{} // SocketVMNet path empty
panicCmd := cfg.StartCmd("shared", networks.SocketVMNet)
// after
cfg, err := networks.LoadConfig() // populates Paths.SocketVMNet from networks.yaml Defensive patterns
Strategy: validation
Validate before calling
if cfg.Paths.SocketVMNet == "" {
return fmt.Errorf("config invalid: paths.socketVMNet must be set")
} Try / catch
func safeStartCmd(cfg *networks.Config, name, daemon string) (cmd string, err error) {
defer func() { if r := recover(); r != nil { err = fmt.Errorf("%v", r) } }()
return cfg.StartCmd(name, daemon), nil
} Prevention
- Load Config via the standard loader, never hand-assemble the struct
- Treat Config as immutable after load; reload rather than mutate
- Keep Paths.SocketVMNet set consistently — both panic guards depend on it
When it happens
Trigger: StartCmd is called on a Config whose Paths.SocketVMNet field is the empty string but which somehow passed the earlier IsDaemonInstalled check — i.e. config mutated concurrently or constructed inconsistently.
Common situations: Programmatically built Config structs that bypass networks.yaml validation; race where the config is reloaded between the check and command construction; hand-assembled Config in tests.
Related errors
- daemon %#q not defined
- daemon %#q is not available
- unexpected daemon %#q
- network %#q is not defined
- unknown daemon type %#q
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/deee2182450e1614.
Report an issue: GitHub.