{"record":{"id":"00bd65b4fd8647ba","repo":"lima-vm/lima","slug":"unexpected-daemon-q","errorCode":null,"errorMessage":"unexpected daemon %#q","messagePattern":"unexpected daemon %#q","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/networks/commands.go","lineNumber":120,"sourceCode":"\tvar cmd string\n\tswitch daemon {\n\tcase SocketVMNet:\n\t\tnw := c.Networks[name]\n\t\tif c.Paths.SocketVMNet == \"\" {\n\t\t\tpanic(\"c.Paths.SocketVMNet is empty\")\n\t\t}\n\t\tcmd = fmt.Sprintf(\"%s --pidfile=%s --socket-group=%s --vmnet-mode=%s\",\n\t\t\tc.Paths.SocketVMNet, c.PIDFile(name, SocketVMNet), c.Group, nw.Mode)\n\t\tswitch nw.Mode {\n\t\tcase ModeBridged:\n\t\t\tcmd += fmt.Sprintf(\" --vmnet-interface=%s\", nw.Interface)\n\t\tcase ModeHost, ModeShared:\n\t\t\tcmd += fmt.Sprintf(\" --vmnet-gateway=%s --vmnet-dhcp-end=%s --vmnet-mask=%s\",\n\t\t\t\tnw.Gateway, nw.DHCPEnd, nw.NetMask)\n\t\t}\n\t\tcmd += \" \" + c.Sock(name)\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unexpected daemon %#q\", daemon))\n\t}\n\treturn cmd\n}\n\nfunc (c *Config) StopCmd(name, daemon string) string {\n\treturn fmt.Sprintf(\"/usr/bin/pkill -F %s\", c.PIDFile(name, daemon))\n}\n","sourceCodeStart":102,"sourceCodeEnd":128,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/networks/commands.go#L102-L128","documentation":"StartCmd ends with a default case that panics with 'unexpected daemon %#q' if the daemon name was not dispatched to a known branch. This can only be hit after the earlier IsDaemonInstalled panic check passed, indicating a daemon string unknown to the command builder — the final guard of the daemon dispatch chain.","triggerScenarios":"Calling StartCmd with a daemon value that passed IsDaemonInstalled (possibly via modified/forked behavior) but is not networks.SocketVMNet, hitting the switch default.","commonSituations":"Forks or patched builds where IsDaemonInstalled accepts extra daemons but StartCmd was not extended; test code passing mock daemon names; typos that coincidentally pass a loose install check.","solutions":["Only pass networks.SocketVMNet to StartCmd","If supporting a new daemon in a fork, add a case to the StartCmd switch","Validate the daemon name against the supported set before building the command"],"exampleFix":"// before\ncmd := cfg.StartCmd(name, \"vde_vmnet\") // panics: unexpected daemon\n// after\ncmd := cfg.StartCmd(name, networks.SocketVMNet)","handlingStrategy":"type-guard","validationCode":"if daemon != networks.SocketVMNet {\n    return fmt.Errorf(\"StartCmd supports only socket_vmnet, got %q\", daemon)\n}","typeGuard":"func startCmdSupports(d string) bool { return d == networks.SocketVMNet }","tryCatchPattern":"func safeStartCmd(cfg *networks.Config, name, daemon string) (cmd string, err error) {\n    defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"%v\", r) } }()\n    return cfg.StartCmd(name, daemon), nil\n}","preventionTips":["Pass only networks.SocketVMNet to StartCmd","Add recover() around StartCmd in tooling that cannot trust its inputs","Extend the StartCmd switch together with any new daemon support"],"tags":["network","daemon","panic","socket-vmnet","go"],"backgroundTag":"unknown-daemon-type","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}