{"record":{"id":"f158c808ee5bed86","repo":"nikivdev/code","slug":"failed-to-disable-service","errorCode":null,"errorMessage":"Failed to disable service: {}","messagePattern":"Failed to disable service: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/macos.rs","lineNumber":725,"sourceCode":"        }\n    }\n\n    // Then disable\n    let target = format!(\"{}/{}\", domain, svc.id);\n    let mut cmd = if svc.service_type.requires_sudo() {\n        let mut c = Command::new(\"sudo\");\n        c.args([\"launchctl\", \"disable\", &target]);\n        c\n    } else {\n        let mut c = Command::new(\"launchctl\");\n        c.args([\"disable\", &target]);\n        c\n    };\n\n    let output = cmd.output()?;\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        bail!(\"Failed to disable service: {}\", stderr);\n    }\n\n    Ok(())\n}\n\n/// Enable a launchd service.\nfn enable_service(svc: &LaunchdService) -> Result<()> {\n    let domain = svc.service_type.domain();\n\n    // First enable\n    let target = format!(\"{}/{}\", domain, svc.id);\n    let mut cmd = if svc.service_type.requires_sudo() {\n        let mut c = Command::new(\"sudo\");\n        c.args([\"launchctl\", \"enable\", &target]);\n        c\n    } else {\n        let mut c = Command::new(\"launchctl\");\n        c.args([\"enable\", &target]);","sourceCodeStart":707,"sourceCodeEnd":743,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/macos.rs#L707-L743","documentation":"disable_service runs an external `launchctl` command and this error is raised when the command exits non-zero; the captured stderr is embedded in the message. It means launchctl itself rejected the disable/bootout operation, not that the tool found no service.","triggerScenarios":"launchctl fails to bootout the service: service not currently loaded, wrong domain (user vs system), sudo required but not used, or malformed plist path.","commonSituations":"Disabling a system-level service without sudo; the service was already unloaded; passing the wrong label/domain so launchctl cannot find the service.","solutions":["Read the embedded stderr in the message — it contains launchctl's actual reason.","Re-run the disable command with sudo if the service lives in the system domain.","Verify the service is currently loaded: `launchctl print <domain>/<label>`; if already unloaded there is nothing to disable.","Confirm the plist path and label are correct before retrying."],"exampleFix":"// before\nflow macos disable my-daemon               // fails: not loaded / no sudo\n// after\nsudo flow macos disable my-daemon          // or ensure service is loaded first","handlingStrategy":"try-catch","validationCode":"let loaded = std::process::Command::new(\"launchctl\")\n    .args([\"print\", &format!(\"gui/{}/{}\", unsafe { libc::geteuid() }, label)])\n    .status()\n    .map(|s| s.success())\n    .unwrap_or(false);\nif !loaded { eprintln!(\"service not loaded; nothing to disable\"); return; }","typeGuard":"fn is_launchctl_stderr(err: &anyhow::Error) -> bool {\n    err.to_string().starts_with(\"Failed to disable service: \")\n}","tryCatchPattern":"match macos::run_disable(opts) {\n    Err(e) if e.to_string().contains(\"Failed to disable service:\") => {\n        let stderr = e.to_string();\n        eprintln!(\"launchctl said: {stderr}\");\n        if stderr.contains(\"Operation not permitted\") { /* rerun with sudo */ }\n    }\n    other => other?,\n}","preventionTips":["Always read the stderr embedded in the error message — it is launchctl's own reason.","Use sudo for services in the system domain.","Confirm the service is loaded before disabling it.","Lint the plist with plutil when configs were recently edited."],"tags":["macos","launchctl","subprocess","service-management"],"backgroundTag":"external-command-exited-nonzero","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}