{"record":{"id":"01180caa0a7699cc","repo":"felixse/FluentTerminal","slug":"command-command-not-found-exit-code-proce","errorCode":null,"errorMessage":"'${command}' command not found. Exit code: ${process.ExitCode}","messagePattern":"'(.+?)' command not found\\. Exit code: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"FluentTerminal.SystemTray/FileFinder.cs","lineNumber":87,"sourceCode":"                        {\n                            throw new Exception(\"Should not happen! 'where' exit code is 0, yet the path is empty.\");\n                        }\n\n                        if (!File.Exists(path))\n                        {\n                            throw new Exception(\n                                \"Should not happen! 'where' returned a path that doesn't exist: \" + path);\n                        }\n\n                        return path;\n                    }\n\n                    if (!string.IsNullOrEmpty(error))\n                    {\n                        throw new Exception($\"'{command}' command not found. Error message: \" + error);\n                    }\n\n                    throw new Exception($\"'{command}' command not found. Exit code: {process.ExitCode:##########}\");\n                }\n            }\n        }\n    }\n}","sourceCodeStart":69,"sourceCodeEnd":92,"githubUrl":"https://github.com/felixse/FluentTerminal/blob/ba83ec485eea8d8ee65825711731300bee2e76ed/FluentTerminal.SystemTray/FileFinder.cs#L69-L92","documentation":"Thrown by FileFinder.GetCommandPath as the final fallback: `where` exited non-zero, no path was returned, AND no error text was captured. This branch reports the raw exit code because the more informative error-message branch did not apply.","triggerScenarios":"The `where` process exited with a non-zero code but produced neither a usable stdout path nor a stderr line within the 50 ms ManualResetEvent window, so `error` is empty and only ExitCode is available.","commonSituations":"`where` exited before output was fully read (race with the 50ms mre.WaitOne); where itself is missing or blocked; antivirus interfered with the child process; PATH lookup failed silently.","solutions":["Confirm `where` exists on the system (it ships with Windows in System32) and is on PATH for the tray process.","Increase the mre.WaitOne timeout or read output synchronously to avoid the race that loses the error text.","Set the profile's shell Location to an absolute path so where-lookup is bypassed.","Re-run with the tool installed and PATH refreshed."],"exampleFix":"// before\nmre.WaitOne(50);\n...\nthrow new Exception($\"'{command}' command not found. Exit code: {process.ExitCode:##########}\");\n\n// after - wait for completion reliably before deciding\nprocess.WaitForExit();\nmre.WaitOne(1000);\nthrow new Exception($\"'{command}' not found (where exit {process.ExitCode}, error: '{error ?? \"<none>\"}').\");","handlingStrategy":"validation","validationCode":"// Read where output synchronously to avoid losing the error to a race.\nvar psi = new ProcessStartInfo(\"where\", command){ UseShellExecute=false, RedirectStandardOutput=true, RedirectStandardError=true };\nvar p = Process.Start(psi); var stdout = p.StandardOutput.ReadToEnd(); var stderr = p.StandardError.ReadToEnd(); p.WaitForExit();\nif (p.ExitCode != 0) throw new Exception($\"'{command}' not found (exit {p.ExitCode}): {stderr}\");","typeGuard":null,"tryCatchPattern":"try { path = command.GetCommandPath(); }\ncatch (Exception ex) { logger.Warn(ex, \"where failed\"); path = fallbackAbsoluteProfilePath; }","preventionTips":["Increase the output-read timeout or read synchronously to avoid the race.","Bypass where by setting an absolute shell path in the profile.","Ensure System32\\where.exe is present and accessible."],"tags":["process","path-lookup","where","windows","race-condition"],"backgroundTag":null,"analyzedSha":"ba83ec485eea8d8ee65825711731300bee2e76ed","analyzedAt":"2026-08-13T21:23:15.467Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}