{"record":{"id":"710bcdb4da133e4a","repo":"aaif-goose/goose","slug":"failed-to-exec-tui-descriptor-err","errorCode":null,"errorMessage":"failed to exec TUI ({descriptor}): {err}","messagePattern":"failed to exec TUI \\((.+?)\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-cli/src/commands/tui.rs","lineNumber":83,"sourceCode":"pub fn handle_tui(args: Vec<String>) -> Result<()> {\n    let source = resolve_source();\n\n    let goose_binary = std::env::current_exe()\n        .context(\"could not determine current goose executable to expose as GOOSE_BINARY\")?;\n\n    let mut cmd = build_command(&source, &args)?;\n    cmd.env(\"GOOSE_BINARY\", &goose_binary);\n\n    let descriptor = match &source {\n        TuiSource::LocalScript(p) => format!(\"node {}\", p.display()),\n        TuiSource::Npx(spec) => format!(\"npx --package {} -- {}\", spec, NPM_BIN_NAME),\n    };\n\n    #[cfg(unix)]\n    {\n        use std::os::unix::process::CommandExt;\n        let err = cmd.exec();\n        Err(anyhow!(\"failed to exec TUI ({descriptor}): {err}\"))\n    }\n\n    #[cfg(not(unix))]\n    {\n        let status = cmd\n            .status()\n            .with_context(|| format!(\"failed to run `{descriptor}`\"))?;\n        if !status.success() {\n            std::process::exit(status.code().unwrap_or(1));\n        }\n        Ok(())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use std::fs;","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/commands/tui.rs#L65-L101","documentation":"On unix the TUI launcher uses Command::exec, which replaces the goose process with node/npx; exec only RETURNS when it fails. So this message always carries a raw OS error: usually NotFound (node or npx missing from PATH), NoSuchFile (local TUI script path wrong), or PermissionDenied. The descriptor names exactly what was exec'd (node <script> or npx --package <spec>).","triggerScenarios":"`goose tui` / TUI launch with Node.js not installed or not on PATH for the goose process; --tui-source pointing at a moved/deleted script; script lacking execute permission; npx wrapper unavailable.","commonSituations":"Minimal containers/servers without node; PATH differing between login shell and the environment goose runs in (launchers, service managers); stale local TUI path after moving the repo.","solutions":["Run the descriptor command yourself (e.g. `node --version`, `npx --version`) to reproduce the exact OS error","Install Node.js or fix PATH so node/npx resolve in goose's environment","For a local script source, verify the path exists and has execute permission","If behind a proxy, ensure npm/npx can fetch the TUI package"],"exampleFix":"# before\ngoose tui        # failed to exec TUI (npx --package @block/goose-tui -- goose-tui): No such file or directory\n# after\nwhich node npx    # both must resolve\nexport PATH=\"$HOME/.nvm/versions/node/v22/bin:$PATH\"\ngoose tui","handlingStrategy":"validation","validationCode":"let node_ok = std::process::Command::new(\"node\")\n    .arg(\"--version\")\n    .output()\n    .map(|o| o.status.success())\n    .unwrap_or(false);\nif !node_ok {\n    anyhow::bail!(\"node not available on PATH; install Node.js before launching the TUI\");\n}","typeGuard":"fn node_available() -> bool {\n    std::process::Command::new(\"node\")\n        .arg(\"--version\")\n        .output()\n        .map(|o| o.status.success())\n        .unwrap_or(false)\n}","tryCatchPattern":"match run_tui(source, args).await {\n    Err(e) if e.to_string().contains(\"failed to exec TUI\") => {\n        if e.to_string().contains(\"NotFound\") || e.to_string().contains(\"No such file\") {\n            // node/npx missing from PATH: surface an install hint\n        }\n        Err(e)\n    }\n    other => other,\n}","preventionTips":["Pre-flight `node --version` and `npx --version` before launching the TUI","Launch goose from a login shell so PATH matches the environment you tested","Pin --tui-source to an existing script path and check it at startup"],"tags":["tui","node","exec","process","environment"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}