{"record":{"id":"b201ff34b1243981","repo":"pranshuparmar/witr","slug":"process-not-managed-by-a-named-launchd-service-s","errorCode":null,"errorMessage":"process not managed by a named launchd service: %s","messagePattern":"process not managed by a named launchd service: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/launchd/plist.go","lineNumber":83,"sourceCode":"\t}\n\n\t// Output format varies:\n\t// - \"system/com.apple.example\" or \"gui/501/com.example.app\" (real service)\n\t// - \"speculative\", \"non-ipc demand\", \"launch job demand\", \"ipc (mach)\" (blame reasons)\n\tline := strings.TrimSpace(string(out))\n\tif line == \"\" {\n\t\treturn \"\", \"\", fmt.Errorf(\"no service label found for pid %d\", pid)\n\t}\n\n\t// Check if this is a real service path (contains \"/\" and starts with domain)\n\tif !strings.Contains(line, \"/\") {\n\t\t// This is a blame reason, not a service label\n\t\t// Try to find the service by querying launchctl list\n\t\tlabel, domain := findServiceByPID(pid)\n\t\tif label != \"\" {\n\t\t\treturn label, domain, nil\n\t\t}\n\t\treturn \"\", \"\", fmt.Errorf(\"process not managed by a named launchd service: %s\", line)\n\t}\n\n\t// Parse domain and label from service path\n\tparts := strings.SplitN(line, \"/\", 2)\n\tif len(parts) < 2 {\n\t\treturn line, \"\", nil\n\t}\n\n\tdomain := parts[0]\n\tlabel := parts[1]\n\n\t// Handle gui/501/label format\n\tif domain == \"gui\" {\n\t\tsubParts := strings.SplitN(label, \"/\", 2)\n\t\tif len(subParts) == 2 {\n\t\t\tdomain = \"gui/\" + subParts[0]\n\t\t\tlabel = subParts[1]\n\t\t}","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/pranshuparmar/witr/blob/dc4fa1da82d3e266fcbd928641b4f30b3077c64f/internal/launchd/plist.go#L65-L101","documentation":"launchctl blame returned a 'blame reason' string (e.g. 'speculative', 'non-ipc demand', 'ipc (mach)') rather than a service path, meaning the process is associated with launchd activity but not attributable to a named service. GetServiceLabel then tries findServiceByPID; when that also finds no label it returns this error including the blame reason.","triggerScenarios":"Calling GetServiceLabel on a process whose blame output contains a slash-less reason string and for which findServiceByPID finds no entry in `launchctl list`: daemons started via legacy mechanisms, xpc/helper processes, or processes whose service is outside the caller's launchd domain.","commonSituations":"Inspecting XPC helper processes of an app; system daemons not visible in the user's gui domain; Spotlight/background agents spawned transiently; running unprivileged so `launchctl list` can't see the owning domain.","solutions":["Run the query as root or in the same launchd domain (gui/UID) as the target so findServiceByPID can see the service.","Check `sudo launchctl list` and `launchctl print system/<label>` manually to locate the owning domain.","Treat the process as not launchd-managed and skip plist enrichment.","Search the plist directories (/System/Library/LaunchDaemons, ~/Library/LaunchAgents) for the executable path instead of relying on blame."],"exampleFix":"// before\nlabel, _, err := launchd.GetServiceLabel(pid) // 'process not managed ...: speculative'\n// after\nlabel, _, err := launchd.GetServiceLabel(pid)\nif err != nil && strings.Contains(err.Error(), \"not managed by a named launchd service\") {\n    // helper/xpc process: fall back to executable path lookup\n    return lookupByExecutablePath(pid)\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"label, domain, err := launchd.GetServiceLabel(pid)\nif err != nil {\n    var nlm *notManagedError\n    if errors.As(err, &nlm) || strings.Contains(err.Error(), \"not managed by a named launchd service\") {\n        return lookupByExecutablePath(pid) // XPC/helper fallback\n    }\n    return err\n}","preventionTips":["Expect blame reasons for XPC helpers and transient agents; have a path-based fallback ready.","Query as root or in the target's launchd domain so findServiceByPID can succeed.","Search plist directories by executable path when blame returns a reason string."],"tags":["macos","launchd","xpc","process-inspection"],"backgroundTag":"process-not-launchd-managed","analyzedSha":"dc4fa1da82d3e266fcbd928641b4f30b3077c64f","analyzedAt":"2026-09-01T12:17:08.767Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}